Skip to content

Commit

Permalink
Merge pull request #32 from testcontainers/support-md
Browse files Browse the repository at this point in the history
Move Quick Start to a separate page
  • Loading branch information
oleg-nenashev authored Jul 15, 2024
2 parents 91cf47f + 4249e4a commit 32c1d6b
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 100 deletions.
108 changes: 10 additions & 98 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# Testcontainers for C/C++ and other native languages

<p align="center">
<!--<a href="https://wiremock.org" target="_blank">-->
<img width="512px" src="docs/images/logo/logo_testcontainers_c_wide.png" alt="Testcontainers for C/C++ Logo"/>
<!--</a>-->
<img width="512px" src="docs/images/logo/logo_testcontainers_c_wide.png" alt="Testcontainers for C/C++ Logo"/>
</p>

[![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/)
Expand All @@ -30,105 +28,19 @@ Also join the `#testcontainers-c` channel on the [Testcontainers Slack](http://s
starting and terminating containers, passing files, exposing ports,
accessing container logs, etc.
- 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](./docs/c/README.md) and [C++](./docs/cpp/README.md) projects.
A fancy C++ wrapper is coming soon
- Support for [Modules](./modules/README.md)
- [Testcontainers for Go](https://golang.testcontainers.org/) under the hood, with all its reporting and resource management capabilities.
Memory might leak a lot in the current versions, but we do not want containers to leak :)
- Support for [C](./docs/c/README.md), [C++](./docs/cpp/README.md), [Swift](./docs/swift/README.md) and other native projects.
- C-style header file for the library. A fancy C++ wrapper is coming soon
- Support for [Testcontainers Modules](./modules/README.md)

## Quick Start

In this section, we will build a demo C application that uses Testcontainers C/C++
for deploying a [WireMock](https://wiremock.org/) API server,
sends a simple HTTP request to this service,
and verifies the response.
We will not be using any C/C++ test framework for that.

For a test framework framework example, see the [Google Test sample project](./demo/google-test/).

### Build the project

Right now you have to check out and build the project to use it locally.
You will need CMake, Docker, Golang 1.19++, and recent C/C++ build tools.
The first build may take a while because the build process will need to download
[Testcontainers for Go](https://github.com/testcontainers/testcontainers-go)
and its dependencies like Docker client libraries,
and then repackage it as a shared library using `go build -buildmode=c-shared`.

```bash
cmake .
cmake --build .
ctest --output-on-failure
```

**Disclaimer:** The commands above may explode, proper coverage on different platforms is yet to be implemented.
At the moment the default compiler and linker options are used, so code is not very portable.
CMake's install option is not being tested at all, stay tuned for package managers.
Any patches and issue reports are welcome!

### Writing a first test

You can use a C/C++ framework for writing tests, e.g. CTest or CppUnit.
Or you can just have a small launcher as presented below.
Below there is a code of the [WireMock demo](./demo/wiremock/) that only uses the library
but not a specialized WireMock module (see below).

Note that in this example, we do not terminate the container,
because Testcontainers for Go injects [Moby Ryuk](https://github.com/testcontainers/moby-ryuk)
sidecar container by default to automatically terminate the instance.
We also do not worry about memory leaks too much, because the process will exit anyway.

#### main.c

<details>
<summary>
main.c - Show me the Code
</summary>

```c
#include <stdio.h>
#include <string.h>
#include "testcontainers-c.h"

#define DEFAULT_IMAGE "wiremock/wiremock:3.0.1-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);
int containerId = ret.r0;
if (!ret.r1) {
printf("Failed to run the container: %s\n", ret.r2);
return -1;
}

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%s\n", response.r0, 200, response.r1, response.r2);
return -1;
}
printf("Server Response: HTTP-%d\n%s\n\n", response.r0, response.r1);
return 0;
}
```

</details>
This is what a very simple run without a test framework may look like.

### Sample output
[![Sample Output](./demo/wiremock/sample_output.png)](./demo/wiremock/README.md)

This is what a very simple run without a test framework may look like.
## Quick Start

[![Sample Output](./demo/wiremock/sample_output.png)](./demo/wiremock/)
Follow the [Getting Started Guide](./docs/getting-started.md).

### Installing the library

Expand Down
93 changes: 93 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Getting Started with Testcontainers for C/C++

In this section, we will build a demo C application that uses Testcontainers for C/C++
for deploying a [WireMock](https://wiremock.org/) API server,
sends a simple HTTP request to this service,
and verifies the response.
We will not be using any C/C++ test framework for that.

For a test framework framework example, see the [demos](../demo/README.md).

## Build the Project

Right now you have to check out and build the project to use it locally.
You will need CMake, Docker, Golang 1.19++, and recent C/C++ build tools.
The first build may take a while because the build process will need to download
[Testcontainers for Go](https://github.com/testcontainers/testcontainers-go)
and its dependencies like Docker client libraries,
and then repackage it as a shared library using `go build -buildmode=c-shared`.

```bash
cmake .
cmake --build .
ctest --output-on-failure
```

**Disclaimer:** The commands above may explode, proper coverage on different platforms is yet to be implemented.
At the moment the default compiler and linker options are used, so code is not very portable.
CMake's install option is not being tested at all, stay tuned for package managers.
Any patches and issue reports are welcome!

## Writing a First Test

You can use a C/C++ framework for writing tests, e.g. CTest or CppUnit.
Or you can just have a small launcher as presented below.
Below there is a code of the [WireMock demo](./demo/wiremock/) that only uses the library
but not a specialized WireMock module (see below).

Note that in this example, we do not terminate the container,
because Testcontainers for Go injects [Moby Ryuk](https://github.com/testcontainers/moby-ryuk)
sidecar container by default to automatically terminate the instance.
We also do not worry about memory leaks too much, because the process will exit anyway.

### main.c

<details>
<summary>
main.c - Show me the Code
</summary>

```c
#include <stdio.h>
#include <string.h>
#include "testcontainers-c.h"

#define DEFAULT_IMAGE "wiremock/wiremock:3.0.1-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);
int containerId = ret.r0;
if (!ret.r1) {
printf("Failed to run the container: %s\n", ret.r2);
return -1;
}

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%s\n", response.r0, 200, response.r1, response.r2);
return -1;
}
printf("Server Response: HTTP-%d\n%s\n\n", response.r0, response.r1);
return 0;
}
```

</details>

## Sample output

This is what a very simple run without a test framework may look like.

[![Sample Output](./demo/wiremock/sample_output.png)](../demo/wiremock/README.md)
4 changes: 2 additions & 2 deletions mkdocs.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
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.
but a C-style shared library adapter for C/C++, Swift, and other native projects.
The project is based on Testcontainers for Go which is one of the most powerful Testcontainers implementations.
copyright: >-
Copyright &copy; 2024 - Oleg Nenashev and all contributors.
Expand All @@ -21,6 +20,7 @@ exclude_docs: |
nav:
- Documentation:
- Overview: README.md
- Getting Started: docs/getting-started.md
- Under the Hood: docs/architecture/README.md
- Usage in C: docs/c/README.md
- Usage in C++: docs/cpp/README.md
Expand Down

0 comments on commit 32c1d6b

Please sign in to comment.