diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..9798bfa --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,4 @@ +FROM python:3.10.4-slim-buster + +RUN apt-get update +RUN apt-get install -y libsass-dev build-essential libcairo2 git libpango-1.0-0 libpangoft2-1.0-0 pangocairo-1.0 pngquant diff --git a/.devcontainer/LICENSE.txt b/.devcontainer/LICENSE.txt new file mode 100644 index 0000000..8938615 --- /dev/null +++ b/.devcontainer/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020-2024 Kento Shimada, Oleg Nenashev, and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 0000000..bb6a34d --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,8 @@ +# Testcontainers for C/C++. DevContainer + +This is an experimental Dev Container for the project site that +does not yet include the build tools. + +## Included Toolchains + +- Python/MkDocs - for the project site and documentation development diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..dd87962 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,31 @@ +// Credits - https://github.com/hitsumabushi845/MkDocs-with-Remote-Containers +{ + "name": "Material for MkDocs", + "dockerFile": "Dockerfile", + "customizations": { + "vscode": { + // Set *default* container specific settings.json values on container create. + "settings": { + "terminal.integrated.shell.linux": "/bin/bash", + "debug.javascript.usePreview": false + }, + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "yzhang.markdown-all-in-one", + "redhat.vscode-yaml", + "shardulm94.trailing-spaces", + "oderwat.indent-rainbow", + "msjsdiag.debugger-for-chrome" + ], + }, + }, + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 8000 + ], + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "pip3 install -r .devcontainer/requirements.txt " + // Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root. + //"remoteUser": "vscode" + } + \ No newline at end of file diff --git a/.devcontainer/requirements.txt b/.devcontainer/requirements.txt new file mode 100644 index 0000000..a0ea223 --- /dev/null +++ b/.devcontainer/requirements.txt @@ -0,0 +1,33 @@ +Markdown==3.5 +MarkupSafe==2.1.3 +mergedeep==1.3.4 +mkdocs==1.6.0 +mkdocs-autorefs==0.5.0 +mkdocs-macros-plugin==1.0.5 +mkdocs-material==9.5.28 +mkdocs-material[imaging]==9.5.28 +mkdocs-multirepo-plugin==0.6.3 +mkdocs-redirects==1.2.1 +mkdocs-extra-sass-plugin==0.1.0 +mkdocs-render-swagger-plugin==0.1.1 +mkdocs-same-dir==0.1.3 +mkdocs-pdf==0.1.1 +livereload==2.6.3 +lxml==4.9.3 +click==8.1.7 +dacite==1.8.1 +ghp-import==2.1.0 +jinja2==3.1.2 +mypy-extensions==1.0.0 +packaging==23.2 +pathspec==0.11.2 +platformdirs==3.11.0 +python-dateutil==2.8.2 +python-slugify==8.0.1 +pyyaml==6.0.1 +pyyaml-env-tag==0.1 +six==1.16.0 +text-unidecode==1.3 +typing-extensions==4.8.0 +typing-inspect==0.8.0 +watchdog==3.0.0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0bc1290..4f0fe14 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,3 +24,32 @@ jobs: run-build: true run-test: true test-args: "--output-on-failure" + + build-site: + runs-on: ubuntu-latest + + permissions: + contents: read + packages: read + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: "true" + + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build in the dev container image + uses: devcontainers/ci@v0.3 + with: + imageName: ghcr.io/oleg-nenashev/oleg-nenashev-site-builder + cacheFrom: ghcr.io/oleg-nenashev/oleg-nenashev-site-builder + push: never + runCmd: | + mkdocs build diff --git a/.github/workflows/deploy-site.yml b/.github/workflows/deploy-site.yml new file mode 100644 index 0000000..c61cab2 --- /dev/null +++ b/.github/workflows/deploy-site.yml @@ -0,0 +1,64 @@ +name: Deploy Site to GitHub Pages + +on: + push: + branches: ["main"] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: true + +jobs: + build-site: + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: "true" + + - name: Setup Pages + id: pages + uses: actions/configure-pages@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build in the dev container image + uses: devcontainers/ci@v0.3 + with: + imageName: ghcr.io/oleg-nenashev/oleg-nenashev-site-builder + cacheFrom: ghcr.io/oleg-nenashev/oleg-nenashev-site-builder + push: always + runCmd: | + mkdocs build + + - name: Upload artifact + # Automatically uploads an artifact from the './_site' directory by default + uses: actions/upload-pages-artifact@v1 + + deploy-site: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build-site + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 diff --git a/.gitignore b/.gitignore index c78ed6d..b292995 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,7 @@ testcontainers-c/testcontainers.h *.dll *.so.0.0.1 *.dll.0.0.1 + +## MkDocs +/.cache +/_site diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 605ce3e..7a58324 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing -[![Slack: testcontainers-c on slacktestcontainers.org](https://img.shields.io/badge/Slack-%23testcontainers%E2%80%94c-brightgreen?style=flat&logo=slack)](http://slack.testcontainers.org/) +[![Slack: testcontainers-c on slack.testcontainers.com](https://img.shields.io/badge/Slack-%23testcontainers%E2%80%94c-brightgreen?style=flat&logo=slack)](https://slack.testcontainers.org/) [![Stability: Experimental](https://masterminds.github.io/stability/experimental.svg)](https://masterminds.github.io/stability/experimental.html) Contributions are welcome! @@ -8,7 +8,7 @@ For any feedback and suggestions, use GitHub Issues. ## Community Slack -We use the `#testcontainers-c` channel on [Testcontainers Slack](http://slack.testcontainers.org/). +We use the `#testcontainers-c` channel on [Testcontainers Slack](https://slack.testcontainers.com/). Please join this channel if you want to discuss contributions/strategy/whatever. GitHub Issues are recommended for most of the proposals and bug reports though. @@ -35,6 +35,20 @@ To skip the demo builds and tests, use the `SKIP_DEMOS` variable: cmake -DSKIP_DEMOS=true . ``` +## Contributing to the Documentation + +The documentation is structured in the MkDocs format and uses Material for MkDocs. +To develop the site in this repository, start it in the [Dev Containers](.devcontainer/README.md) +and use the following commands: + +```shell +mkdocs serve +``` + +```shell +mkdocs build +``` + ## Codestyle ### Public APIs diff --git a/LICENSE b/LICENSE index eb10283..5253bd6 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Oleg Nenashev, WireMock Inc and all contributors +Copyright (c) 2023-2024 Oleg Nenashev, WireMock Inc. and all contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 364b324..479c61a 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,10 @@ [![Stability: Experimental](https://masterminds.github.io/stability/experimental.svg)](https://masterminds.github.io/stability/experimental.html) [![GitHub release (latest by date)](https://img.shields.io/github/v/release/oleg-nenashev/testcontainers-c)](https://github.com/oleg-nenashev/testcontainers-c/releases) -> **WARNING**: This is a prototype. -> There is a lot to do before it can be distributed and used in production, -> see the GitHub Issues. -> The plan is to provide vcpkg and Conan packages; now it is an importable CMake project. -> A feasible level of feature parity with Testcontainers Go is needed too, -> hence a lot of wrapper coding. +!!! warning + This is a prototype. + There is a lot to do before it can be distributed and used in production, see the GitHub Issues + and the [project roadmap](./ROADMAP.md) This is not a standalone [Testcontainers](https://testcontainers.org/) engine, but a C-style shared library adapter for native languages like C/C++, D, Lua, Swift, etc. @@ -34,8 +32,9 @@ Also join the `#testcontainers-c` channel on the [Testcontainers Slack](http://s - Minimum HTTP client wrapper to simplify requests and assertions - [Testcontainers for Go](https://golang.testcontainers.org/) under the hood - Wrappers for native C types to minimize Golang conversion code on the user side -- Support for C and C++ projects. A fancy C++ wrapper is coming soon -- Support for Modules, e.g. the [WireMock module](./modules/wiremock/) +- Support for [C](./docs/c/README.md) and [C++](./docs/cpp/README.md) projects. + A fancy C++ wrapper is coming soon +- Support for [Modules](./modules/README.md) ## Quick Start @@ -144,97 +143,21 @@ cmake --install .. ## Documentation -Coming soon: guidelines, specs and code documentation. Check out the examples for now. +### Using in C/C++/Swift projects -## Usage in C/C++ +- [C projects](./docs/c/README.md) +- [C++ projects](./docs/cpp/README.md) +- [Swift projects](./docs/swift/README.md) -- [Using the generic Testcontainer C API](./demo/generic-container/) -- [Using Testcontainers C in Google Test (C++)](./demo/google-test/) -- [Using the WireMock module](./demo/wiremock/) +See [the examples and demos](./demo/README.md) for more examples. -See [the examples and demos](./demo/) for more examples. - -## Usage in other languages +### Using in other languages TL;DR: You get the C header file, a shared library object or a DLL file from the -[Testcontainers C](./testcontainers-c/) module, +[Testcontainers C](./docs/c/README.md) module, Then, you know the drill. Feel free to contribute examples or SDKs for the languages! -## Modules - -As for other Testcontainers implementations, Testcontainers for C/C++ allow writing -extensions that extend the SDK and APIs to make usage of a particular service provider -easier. -The expectation is that the modules are implemented in a separate dynamic library -and linked to the consumer project. - -### Available modules - -- Generic container for DYI containers (embedded) - - [Demo](./demo/generic-container/) -- [WireMock](./modules/wiremock/) - for API mocking and integration testing - - [Demo](./demo/wiremock/) - -### Why modules? - -Modules help to simplify test development and maintenance by encapsulating -domain-specific logic of a target container. -For example, the WireMock module adds an API to simplify the configuration of the container. -You can also use modules to create specific asserts for the container, -or even attach full-fledged API clients for fine-grain testing. - -Initializing WireMock with the module: - -```c -#include "testcontainers-c-wiremock.h" - -int main() { - printf("Creating new container: %s\n", DEFAULT_WIREMOCK_IMAGE); - int requestId = tc_wm_new_default_container(); - tc_wm_with_mapping(requestId, "test_data/hello.json", "hello"); - struct tc_run_container_return ret = tc_run_container(requestId); - - // ... -} -``` - -The same initialization without a module (using the "Generic Container" API): - -
- -Show me the Code - - -```c -#include "testcontainers-c.h" - -#define DEFAULT_IMAGE "wiremock/wiremock:3.1.0-1" - -int main() { - printf("Using WireMock with the Testcontainers C binding:\n"); - - printf("Creating new container: %s\n", DEFAULT_IMAGE); - int requestId = tc_new_container_request(DEFAULT_IMAGE); - tc_with_exposed_tcp_port(requestId, 8080); - tc_with_wait_for_http(requestId, 8080, "/__admin/mappings"); - tc_with_file(requestId, "test_data/hello.json", "/home/wiremock/mappings/hello.json"); - struct tc_run_container_return ret = tc_run_container(requestId); - - // ... -} -``` - -
- -### Creating new modules - -You are welcome to contribute more modules in this or a standalone repository! - -> **NOTE:** Some modules are stored in this repository for demo and prototyping purposes. -> If you develop new modules, once `vcpkg` or `Conan` packaging is implemented for Testcontainers C, -> you might want to develop your module in a standalone repository instead. - ## Credits Using a complex Golang framework from C/C++ is not trivial. diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..d2f6c4c --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,26 @@ +# Testcontainers for C/C++. Roadmap + +A full public roadmap is coming soon. +See the [GitHub Issues](https://github.com/testcontainers/testcontainers-c/issues) and, +in particular, +the pinned issues to learn about the key initiatives on the table. + +## Key Objectives + +- Ensure sufficient feature parity with Testcontainers for Go ([#6](https://github.com/testcontainers/testcontainers-c/issues/6)) +- Add a C++ binding library and class-based headers ([#12](https://github.com/testcontainers/testcontainers-c/issues/12)) +- Prototype and document support for other languages that + leverage native libraries, in particular Swift +- Make Testcontainers for C/C++ an official project + listed on the [Testcontainers site](https://testcontainers.com/) +- Publish the project to common C/C++ package managers + ([vcpkg](https://github.com/testcontainers/testcontainers-c/issues/2), + [Conan](https://github.com/testcontainers/testcontainers-c/issues/3)) + +## Contributing + +All contributions are welcome! +This is a small project, and everyone is welcome to take a lead +on the initiative they are interested in (within the roadmap or not), +and drive it to completion. +See the [Contributor Guide](CONTRIBUTING.md). diff --git a/demo/README.md b/demo/README.md new file mode 100644 index 0000000..0b44cab --- /dev/null +++ b/demo/README.md @@ -0,0 +1,7 @@ +# Project Demos + +## Usage in C/C++ + +- [Using the generic Testcontainer C API](./generic-container/README.md) +- [Using Testcontainers C in Google Test (C++)](./google-test/README.md) +- [Using the WireMock module](./wiremock/README.md) diff --git a/docs/architecture/README.md b/docs/architecture/README.md new file mode 100644 index 0000000..3671b1f --- /dev/null +++ b/docs/architecture/README.md @@ -0,0 +1,5 @@ +# Architecture + +!!! note + This section is coming soon. + All contributions are welcome, just submit a pull request! diff --git a/docs/c/README.md b/docs/c/README.md new file mode 100644 index 0000000..ef5ccf2 --- /dev/null +++ b/docs/c/README.md @@ -0,0 +1,139 @@ +# Using Testcontainers for C + +You can use the `testcontainers-c` library with common C +unit testing frameworks and, soon, with package managers. + +!!! note + This section is coming soon. + All contributions are welcome, just submit a pull request! + +## Installing the library + +For now, you can build and install the library locally. +You can also use CPM in CMake, or another similar tool +that automates pulling and building of CMake projects from GitHub, + +### Building locally + +You need CMake 3.16.3 and Golang 1.19+. +At the moment there are not so many configuration flags, so the build is straightforward: + +```shell +cmake . +cmake --build . +ctest --output-on-failure +``` + +### Installing with CPM + +You can also use [CPM](https://github.com/cpm-cmake/CPM.cmake) in CMake: + +```cmake +include(cmake/CPM.cmake) +CPMAddPackage( + NAME testcontainers-c + VERSION 0.0.2 + GITHUB_REPOSITORY "testcontainers/testcontainers-c" + OPTIONS "SKIP_DEMOS TRUE") +``` + +## Using the Library + +!!! note + More frameworks will be documented soon. + All contributions are welcome, just submit a pull request! + +### CMake Tests (CTest) + +The first way to use Testcontainers are building native executables with them. +Some frameworks like CTest provide wrappers for such executables. +In such examples, you do not even have to worry about releasing the Testcontainers resources, because +Testcontainers for Go has automatic resource de-provisioning. + +#### Initializing the Testcontainer + +```c +#include +#include +#include "testcontainers-c-wiremock.h" + +int main() { + printf("Using WireMock with the Testcontainers C binding:\n"); + + printf("Creating new container: %s\n", DEFAULT_WIREMOCK_IMAGE); + int requestId = tc_wm_new_default_container(); + //FIXME: This method is bogus + tc_wm_with_mapping(requestId, "test_data/hello.json", "hello"); + tc_with_file(requestId, "test_data/hello.json", "/home/wiremock/mappings/hello2.json"); + struct tc_run_container_return ret = tc_run_container(requestId); + int containerId = ret.r0; + if (!ret.r1) { + printf("Failed to run the container: %s\n", ret.r2); + if (containerId != -1) { // Print container log + char* log = tc_get_container_log(containerId); + if (log != NULL) { + printf("\n%s\n", log); + } + } + return -1; + } +``` + +#### Testing the Startup + +```c + printf("Getting WireMock stub API mappings to test initialization\n"); + struct WireMock_Mapping mapping = tc_wm_get_mappings(containerId); + if (mapping.responseCode != 200) { + printf("Failed to get WireMock mapping: %s\n", mapping.error); + return -1; + } else { + printf("WireMock Mapping:\n%s\n", mapping.json); + } +``` + +#### Sending a Test Request + +As a first step, you can send a test request to the container. +Then, this code will be replaced by a real test of your application. + +```c + printf("Sending HTTP request to the container\n"); + struct tc_send_http_get_return response = tc_send_http_get(containerId, 8080, "/hello"); + if (response.r0 == -1) { + printf("Failed to send HTTP request: %s\n", response.r2); + return -1; + } + if (response.r0 != 200) { + printf("Received wrong response code: %d instead of %d\n%s\n", response.r0, 200, response.r2); + return -1; + } + printf("Server Response: HTTP-%d\n%s\n\n", response.r0, response.r1); + return 0; +} +``` + +In CMake, once the `testcontainers-c` is installed (see above), +you can use it in test executables built by CMake: + +```cmake +enable_testing() +file(COPY test_data DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + +add_executable(${TARGET_OUT} mytest.cpp) +add_dependencies(${TARGET_OUT} testcontainers-c-shim) +target_link_libraries(${TARGET_OUT} PRIVATE testcontainers-c) +add_test(NAME wiremock_module_demo COMMAND ${TARGET_OUT}) +``` + +After building the project, you can run `ctest`: + +```shell +cmake --build . +ctest --output-on-failure +``` + +## Demos + +- [Using the generic Testcontainers C API](../../demo/generic-container/README.md) +- [Using the WireMock module](../../demo/wiremock/README.md) diff --git a/docs/cpp/README.md b/docs/cpp/README.md new file mode 100644 index 0000000..c0913ed --- /dev/null +++ b/docs/cpp/README.md @@ -0,0 +1,64 @@ +# Using Testcontainers in C++ + +At the moment, there is no dedicated C++ binding library/header, +but it is on [our roadmap](../../ROADMAP.md). +Tou can use the `testcontainers-c` library directly +in all C++ testing frameworks. + +## Google Test + +Like in other unit test frameworks, +in [GoogleTest](https://google.github.io/googletest/) you can deploy a Testcontainers as a test fixture, +with proper setup and tear-down methods. + +```cpp +#include +#include +#include +#include "testcontainers-c.h" + +class WireMockTestContainer : public ::testing::Test { + +const char* WIREMOCK_IMAGE = "wiremock/wiremock:3.0.1-1"; +const char* WIREMOCK_ADMIN_MAPPING_ENDPOINT = "/__admin/mappings"; + +protected: + void SetUp() override { + std::cout << "Creating new container: " << WIREMOCK_IMAGE << '\n'; + int requestId = tc_new_container_request(WIREMOCK_IMAGE); + tc_with_exposed_tcp_port(requestId, 8080); + tc_with_wait_for_http(requestId, 8080, WIREMOCK_ADMIN_MAPPING_ENDPOINT); + tc_with_file(requestId, "test_data/hello.json", "/home/wiremock/mappings/hello.json"); + + struct tc_run_container_return ret = tc_run_container(requestId); + containerId = ret.r0; + + EXPECT_TRUE(ret.r1) << "Failed to run the container: " << ret.r2; + }; + + void TearDown() override { + char* error = tc_terminate_container(containerId); + ASSERT_EQ(error, nullptr) << "Failed to terminate the container after the test: " << error; + }; + + int containerId; +}; +``` + +Then, you can define new tests by referring to the container via `containerId`. + +```cpp +TEST_F(WireMockTestContainer, HelloWorld) { + std::cout << "Sending HTTP request to the container\n"; + struct tc_send_http_get_return response = tc_send_http_get(containerId, 8080, "/hello"); + + ASSERT_NE(response.r0, -1) << "Failed to send HTTP request: " << response.r2; + ASSERT_EQ(response.r0, 200) << "Received wrong response code: " << response.r1 << response.r2; + + std::cout << "Server Response: HTTP-" << response.r0 << '\n' << response.r1 << '\n'; +} +``` + +## Demos + +- [Using Testcontainers C in Google Test (C++)](../../demo/google-test/) diff --git a/docs/swift/README.md b/docs/swift/README.md new file mode 100644 index 0000000..3ca1aee --- /dev/null +++ b/docs/swift/README.md @@ -0,0 +1,5 @@ +# Using Testcontainers in Swift + +!!! note + This section is coming soon. + All contributions are welcome, just submit a pull request! diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..bcc5723 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,110 @@ +site_name: Testcontainers for C/C++ +site_description: >- + Testcontainers for C/C++ is not a standalone Testcontainers engine, + but a C-style shared library adapter for native languages + like C/C++, D, Lua, Swift, etc. + The project is based on Testcontainers for Go which is one of the most powerful Testcontainers implementations. +copyright: >- + Copyright © 2024 - Oleg Nenashev and all contributors. +repo_url: https://github.com/testcontainers/testcontainers-c +repo_name: GitHub Repo +edit_uri: edit/main/ +site_url: https://testcontainers.github.io/testcontainers-c + +# Build +site_dir: _site +docs_dir: . +exclude_docs: | + /_deps/** + !.devcontainer + +nav: + - Documentation: + - Overview: README.md + - Under the Hood: docs/architecture/README.md + - Usage in C: docs/c/README.md + - Usage in C++: docs/cpp/README.md + - Usage in Swift: docs/swift/README.md + - Demos: + - All Demos: demo/README.md + - Generic Container: demo/generic-container/README.md + - WireMock Module: demo/wiremock/README.md + - Modules: + - Overview: modules/README.md + - Embedded Modules: + - WireMock: modules/wiremock/README.md + - Roadmap: ROADMAP.md + - Contributing: CONTRIBUTING.md + +plugins: + - search + - autorefs + - macros: + include_dir: . + on_error_fail: true + on_undefined: strict + - mkdocs-pdf + - social + - same-dir + - redirects: + redirect_maps: + +# Markdown +markdown_extensions: + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.superfences + - pymdownx.tabbed: + alternate_style: true + - toc: + permalink: '#' + - attr_list + - admonition + - pymdownx.details + - pymdownx.superfences + +# Theme +theme: + name: material + highlightjs: true + features: + - announce.dismiss + - content.action.edit + - content.action.view + - content.code.annotate + - content.code.copy + - content.code.select + - content.tabs.link + - content.tooltips + # - header.autohide + # - navigation.expand + - navigation.footer + # NOT compatible qith toc.integrate + # - navigation.indexes + - navigation.path + # - navigation.instant + # - navigation.instant.prefetch + # - navigation.instant.progress + # - navigation.prune + - navigation.sections + - navigation.expand + - navigation.tabs + # - navigation.tabs.sticky + - navigation.top + - navigation.tracking + - search.highlight + - search.share + - search.suggest + - toc.follow + - toc.integrate + font: + text: DM Sans + code: Roboto Mono + favicon: docs/images/logo/logo_testcontainers_c_square.png + logo: docs/images/logo/logo_testcontainers_c_square.png + icon: + repo: fontawesome/brands/github diff --git a/modules/README.md b/modules/README.md new file mode 100644 index 0000000..7380d82 --- /dev/null +++ b/modules/README.md @@ -0,0 +1,82 @@ +# Testcontainers for C/C++. Modules + +As for other Testcontainers implementations, Testcontainers for C/C++ allow writing +extensions that extend the SDK and APIs to make usage of a particular service provider +easier. +The expectation is that the modules are implemented in a separate dynamic library +and linked to the consumer project. + +The modules use Native API, and +can be a fully native implementation or +a Golang bridge one, similar to the core project. + +## Why Modules? + +Modules help to simplify test development and maintenance by encapsulating +domain-specific logic of a target container. +For example, the WireMock module adds an API to simplify the configuration of the container. +You can also use modules to create specific asserts for the container, +or even attach full-fledged API clients for fine-grain testing. + +## Available Modules + +The following modules are available for this project: + +- Embedded Generic container for DYI containers - [DEMO](../demo/generic-container/README.md) +- [WireMock for API Mocking](./wiremock/README.md) + +## Using Modules + +Initializing WireMock with the module: + +```c +#include "testcontainers-c-wiremock.h" + +int main() { + printf("Creating new container: %s\n", DEFAULT_WIREMOCK_IMAGE); + int requestId = tc_wm_new_default_container(); + tc_wm_with_mapping(requestId, "test_data/hello.json", "hello"); + struct tc_run_container_return ret = tc_run_container(requestId); + + // ... +} +``` + +The same initialization without a module (using the "Generic Container" API): + +
+ +Show me the Code + + +```c +#include "testcontainers-c.h" + +#define DEFAULT_IMAGE "wiremock/wiremock:3.1.0-1" + +int main() { + printf("Using WireMock with the Testcontainers C binding:\n"); + + printf("Creating new container: %s\n", DEFAULT_IMAGE); + int requestId = tc_new_container_request(DEFAULT_IMAGE); + tc_with_exposed_tcp_port(requestId, 8080); + tc_with_wait_for_http(requestId, 8080, "/__admin/mappings"); + tc_with_file(requestId, "test_data/hello.json", "/home/wiremock/mappings/hello.json"); + struct tc_run_container_return ret = tc_run_container(requestId); + + // ... +} +``` +
+ +## Creating New Modules + +Just do it! Any pull requests are welcome, +and you can also create modules as standalone repositories. + +### Where to Publish Modules? + +Some modules are stored in [this repository](https://github.com/testcontainers/testcontainers-c) for demo and prototyping purposes. +You are welcome to add your modules there too. +If you develop new modules, once `vcpkg` or `Conan` packaging is implemented for Testcontainers C, +you might want to develop your module in a standalone repository instead.