问题
I want to write a functional test case that tests a program with a known value for random numbers. I have already tested it with mocks during the unit testing. But I would like that for functional testing as well (not all of them, of course :)
What is the easiest way to have /dev/urandom
overridden for just one process? Is there a way to do something like a chroot
for a single file and let all the others 'pass through'?
回答1:
If your system is new enough (e.g. RHEL 7) and supports setns
syscall it can be done with the help of mount namespaces. Root access is required.
The idea is to create a separate mount namespace for the process, and inside that namespace bind-mount some other file or FIFO over /dev/random
so that the processes from this mount namespace would read the data from this bind-mounted file. Other processes will see the regular /dev/random
.
Here is how to do that.
Preparation: run the following command to make all this staff work (as it may not work by default, see this question for details).
# mount --make-rprivate /
Now let's create a shell running inside a new mount namespace.
# unshare -m /bin/bash
You have the new bash
started which has its own mount namespace. You can compare the result of the following command from inside this shell and from some other shell:
This shell:
# ls -l /proc/self/ns/mnt
lrwxrwxrwx. 1 root root 0 Sep 26 16:06 /proc/self/ns/mnt -> mnt:[4026532148]
Other shell:
$ ls -l /proc/self/ns/mnt
lrwxrwxrwx. 1 ec2-user ec2-user 0 Sep 26 16:06 /proc/self/ns/mnt -> mnt:[4026531840]
Note that the numbers differ, so the two shells are in the different mount namespaces and the mounts performed from the first shell will not be visible to other processes in the system (except all the children of this shell).
Now in this shell we can bind-mount something over the existing /dev/random
.
# echo 'some large text' > /tmp/fakerandom
# mount --bind /tmp/fakerandom /dev/random
Other processes don't see that, for them /dev/random
works as usual:
$ ls -l /dev/random
crw-rw-rw-. 1 root root 1, 8 Sep 26 15:45 /dev/random
$ cat /dev/random
�Znp7�v�c��Ω^C
But in our shell it's special:
# ls -l /dev/random
-rw-r--r--. 1 root root 16 Sep 26 16:18 /dev/random
# cat /dev/random
some large text
For the functional testing you may want to substitute /dev/random
with some FIFO and write some known data to that FIFO in some other process (see mkfifo(1)
for more information on that if needed).
More information about mount namespaces can be found in this excellent article.
来源:https://stackoverflow.com/questions/26053875/bypass-dev-urandomrandom-for-testing