Skip to content

Initial C++ library#54

Merged
oleg-nenashev merged 9 commits into
testcontainers:mainfrom
seffradev:cpp-abstraction
May 31, 2026
Merged

Initial C++ library#54
oleg-nenashev merged 9 commits into
testcontainers:mainfrom
seffradev:cpp-abstraction

Conversation

@seffradev
Copy link
Copy Markdown
Contributor

@seffradev seffradev commented Aug 10, 2025

What does this PR do?

It implements an initial C++ adapter library design.

  • Documentation for the methods and classes implemented
  • Contribution documentation
  • Mapping of existing functionality in the C library

It depends on #53.

Why is it important?

It provides idiomatic C++, utilizing RAII patterns.

Related issues

@oleg-nenashev
Copy link
Copy Markdown
Collaborator

@seffradev it would be great if you could merge it with main

@oleg-nenashev oleg-nenashev added the enhancement New feature or request label Oct 20, 2025
Comment thread testcontainers-cpp/testcontainers.hpp Outdated
tc_container_terminate(request_id);
}

std::expected<void, std::string> run() {
Copy link
Copy Markdown
Contributor

@SapiensAnatis SapiensAnatis Nov 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New to this repo but just thought I'd take a look at what this API may look like as I want to consume the library from C++.

Am I right in thinking the use of std::expected here in this header which a user is expected to include, means that the library is only usable from C++23 and above?

If so I think it may be worth reconsidering, many projects including my one are still on C++20 or C++17.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion! If I find the time, I could add the project zeus-cpp/expected with a compilation conditional to either use the polyfill or the standard implementation.

Another thing worth addressing is that I am currently working on an alternative library design using the builder pattern for container creation so future revisions (as this is an early draft) may change.

Thanks for your interest!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, such an polyfill backport could work.
On my own, I would have probably just used Boost:Outcome, but I am too attached to Boost from the past.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re builder pattern - I know the database containers will execute scripts in a standard location but those can be hard to keep in sync with the rest of the system. It would be better to use a standard tool like liquibase or flyway.

My solution was a local driver extension that loaded the database as part of the container's startup sequence. I would have to find the code but I think I used a hook just after the 'is the server ready?' call, but had a small amount of concern that it might be lost if somebody else extended this class and forgot to call 'super.hook()'.

The first lesson from this is that any 'hooks' should be backed by a list of actions instead of a single method. It avoids the risk of extensions forgetting to call 'super.hook()' AND allows developer to replace complex implementations with a series of smaller ones.

The second less is that this is a really valuable extension to the container logic since it frees the developer from any need to explicitly configure the container's database beyond adding a single line to the builder. Flyway loads the files under resources/db/migration/, I don't know what directory liquibase uses. This would need to be configurable though - tests might want to use simplified schemas or preloaded data.

There's a few odd tweaks to this, e.g., if you want to support multiple databases, but they're not common and there are workarounds.

(Think copying localized text from a primary PostgreSQL database into a SQLite database that's then distributed to each host. This reduces the load on the primary database but more importantly makes it impossible for an attacker to "scribble" on the displayed HTML on more than a single server at a time.)

I'll try to find my existing code to clean up and submit as a suggestion. It's clearly not a one-shot - you need to support multiple languages, multiple database migration tools, etc. - but it could be a starting point for these implementations. Plus it might be possible to move the code onto the docker image so the developer would only need to mount the appropriate directory to the container.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@beargiles I am not sure it was the target repo/thread

Copy link
Copy Markdown
Collaborator

@oleg-nenashev oleg-nenashev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to merge with main after I get #58 over the line.
I do not mind if we merge this experimental codebase first @seffradev . As long as it builds, having a boilerplate in the repo looks reasonable to me, the whole repo is experimental ATM


add_library(${TARGET} INTERFACE)

set(CMAKE_CXX_STANDARD 23)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FTR I am fine with doing only 23 for now, that's not a blocker

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My biggest argument against merging what we have is that I have a redesign almost done. I just have some UB to refine away.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine by me

@seffradev seffradev force-pushed the cpp-abstraction branch 2 times, most recently from b0f89b5 to 35d2e8c Compare December 28, 2025 18:35
@oleg-nenashev
Copy link
Copy Markdown
Collaborator

OK. I am on standby. Let me know once it is ready for review/integration. And thank you!

@seffradev
Copy link
Copy Markdown
Contributor Author

Perfect. I'm currently fighting the compiler, as I'm using a bit too modern C++ with an even more modern compiler on my machine than what's in the CI.

@seffradev seffradev marked this pull request as ready for review December 28, 2025 19:07
@oleg-nenashev
Copy link
Copy Markdown
Collaborator

Perfect. I'm currently fighting the compiler, as I'm using a bit too modern C++ with an even more modern compiler on my machine than what's in the CI.

Dev Containersfor the win. We can update it as needed, no need to stick with older versions as of now

Copy link
Copy Markdown
Collaborator

@oleg-nenashev oleg-nenashev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for integrating. I can finish packaging on the top of it

@seffradev seffradev force-pushed the cpp-abstraction branch 4 times, most recently from a441417 to a88304c Compare March 7, 2026 23:36
@oleg-nenashev
Copy link
Copy Markdown
Collaborator

@seffradev, do you think we can go ahead? I am preparing to work on this repo again during the vacation in July, so it might be great to have all the major code merged into main. There will be some work to unravel and to synchronize #66 , but it can be done on main too

@seffradev
Copy link
Copy Markdown
Contributor Author

@oleg-nenashev it's fit for merging!

@oleg-nenashev
Copy link
Copy Markdown
Collaborator

I will stabilize the PR inside main today. There are some extra patches to be done while updating Testcontainers for Go

@oleg-nenashev oleg-nenashev merged commit 260eac4 into testcontainers:main May 31, 2026
1 of 3 checks passed
@oleg-nenashev oleg-nenashev mentioned this pull request May 31, 2026
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add C++ binding library

4 participants