Automated Tests Advice, C# Edition
This post is part of C# Advent Calendar 2021.
I do like writing automated tests, for two reasons. First, it gives me a fast feedback loop. Testing on the fully running app is usually time-consuming compared to running a test. Second, over time it gives some confidence that changes in the code didn’t break your application in unexpected ways.
Basic Process information via /proc
When you need information about a process in Linux,
there are tons of command lines tools, like ps
, htop
, lsof
etc.
I often do not remember the flags to get the information I want.
Luckily, Linux has the /proc file system which gives details on every process.
Most Unix-like operation systems have it, but the formats differ.
I only take a look at the Linux version here.
Tests Not Running: JUnit 5, Maven and Spring Boot Magic
I recently worked on an existing Spring Boot based codebase. Everything looked fine and kept adding new features and improving the codebase. I wrote my tests and run the test suite in my IDE. My changes got into production and everything looked fine.
A few weeks later I took a look at the Continues Integration Servers logs of that project and noticed that the tests are not running. That is no good. My local setup is not a reliable environment, for example, I can forget to check in a file into version control. And I usually run a reduced set of tests and rely on the CI system to run the whole tests suite.
When a Pipe isn't enough: TTYs in Java
I needed to launch Docker containers in Java and pipe the result pack to some other place. This included interacting with that container directly via standard in/out. Nothing easier than that, you can do this with docker like this:
docker run -it ubuntu:20.04
Ok, then lets launch it via Java:
var processCreation = new ProcessBuilder("docker", "run", "-it", "ubuntu:20.04");
processCreation.redirectErrorStream();
processCreation.redirectOutput();
processCreation.redirectInput();
var process = processCreation.start();
redirectToRightPlace(process.getInputStream());
redirectToRightPlace(process.getErrorStream());
redirectToRightPlace(process.getOutputStream());
int exitCode = process.waitFor();
Unfortunately, you get this error back from the process:
the input device is not a TTY
Event when you ignore this error, interactive apps like a shell, text editors etc won’t work properly. So, what is this TTY anyway?
Recently I’ve been working with Docker, launching non-root containers.
Mostly because I mounted files into the container I didn’t want every file to be owned by root.
I use commands like this:
docker run --user="$(id --user):$(id --group) -v $PWD:/mounted-directory <image> <comand>
.
This way the processes inside the container use the same user id as the current user,
so any file created inside the container on the mounted directory can easily be read and changed.
What happens if you pick a random user id, one which doesn’t exist? Try it:
docker run --detach --rm --user=42421:42421 busybox sleep 10
> 542d4de888751e6d067ddd84bf3b9f21698e2af4a0a90844b586c92a3d47d6d
ps aux | grep sleep
> 42421 88497 0.0 0.0 1308 4 ? Ss 14:28 0:00 sleep 10
> roman 88539 0.0 0.0 6404 2292 pts/11 S+ 14:28 0:00 grep --color=auto sleep