ovsdb数据库是NOSQL数据库的一种,大部分人应该都没有听说过这个数据库。虽然这个数据库默默无闻,但是它在交换机以及云计算这两个方向上占据了比较重要的地位。
本人所在的公司恰好也用到了这个数据库。平时虽然经常使用这个数据库,但是关于这个数据库是如何来实现的,还真是不清楚。所以在工作之余,心里就产生了读一读它的源代码的想法。说干就干,直接从github下载了源代码,放到了机器上,编译出来了程序,当我撸起袖子,准备大干一场的时候,现实如当头棒喝,令我头疼不已。
从开读到现在,我大致花了3个月的空闲时间,虽然如此,总感觉效率低下,读代码不得其法。3个月的空闲时间,大体只读了它的各个基础设施,如map,hash,set,mutex等的实现,总感觉有心无力。
原因很简单,我对这个数据库只是了解了一个大概,知道它和json联系紧密,我甚至不懂这个东西怎么建表,怎么插入。代码读着读着,就不知道在干什么了,所以没什么成就感,老是读不下去。而且比较要命的是,这个数据库貌似没有太多的例子,告诉你怎么建表,怎么插入,怎么删除,直接丢给你一个RFC7047,告诉你怎么构造json串和ovsdb-server通信,看到这些我头都大了。当然最为重要的一点是工作忙的很,压根没有心思细细钻研代码,所以一拖再拖。
好不容易春节放假了,这段时间尽量不要浪费。所以就产生了过一遍代码的念头。所以仔细读了一下它的安装说明,然后又摸索了一番,终于发现了高效读ovsdb实现的方法了。所以在这里记录一番,与诸位共勉。
秘诀就是测试驱动。
其实在源程序的INSTALL.md中有这样一番说明:
Testsuites
==========
This section describe Open vSwitch's built-in support for various test
suites. You must bootstrap, configure and build Open vSwitch (steps are
in "Building and Installing Open vSwitch for Linux, FreeBSD or NetBSD"
above) before you run the tests described here. You do not need to
install Open vSwitch or to build or load the kernel module to run
these test suites. You do not need supervisor privilege to run these
test suites.
Self-Tests
----------
Open vSwitch includes a suite of self-tests. Before you submit patches
upstream, we advise that you run the tests and ensure that they pass.
If you add new features to Open vSwitch, then adding tests for those
features will ensure your features don't break as developers modify
other areas of Open vSwitch.
Refer to "Testsuites" above for prerequisites.
To run all the unit tests in Open vSwitch, one at a time:
make check
This takes under 5 minutes on a modern desktop system.
To run all the unit tests in Open vSwitch, up to 8 in parallel:
make check TESTSUITEFLAGS=-j8
This takes under a minute on a modern 4-core desktop system.
To see a list of all the available tests, run:
make check TESTSUITEFLAGS=--list
To run only a subset of tests, e.g. test 123 and tests 477 through 484:
make check TESTSUITEFLAGS='123 477-484'
(Tests do not have inter-dependencies, so you may run any subset.)
To run tests matching a keyword, e.g. "ovsdb":
make check TESTSUITEFLAGS='-k ovsdb'
To see a complete list of test options:
make check TESTSUITEFLAGS=--help
The results of a testing run are reported in tests/testsuite.log.
Please report test failures as bugs and include the testsuite.log in
your report.
意思很明显,那就是我们其实可以运行单元测试,单元测试其实是通过Makefile来驱动的,仔细去翻阅Makefile文件,你会发现,这个东西其实是通过调用tests目录下的testsuits来执行单元测试的。
比如说我们想要测试ovsdb,那么执行
make check TESTSUITEFLAGS='-k ovsdb'
追踪一下,可以发现,这个东西实际上最后会执行:
./tests/testsuite -C tests AUTOTEST_PATH=utilities:vswitchd:ovsdb:vtep:tests::ovn/controller-vtep:ovn/northd:ovn/utilities:ovn/controller -k ovsdb
也就是调用tests目录下的testsuite来执行单元测试,testsuits是什么,其实它只是一个shell脚本而已,虽然它表现得像是一个程序而已。
% testsuite -h 127 ↵
Usage: ./testsuite [OPTION]... [VARIABLE=VALUE]... [TESTS]
Run all the tests, or the selected TESTS, given by numeric ranges, and
save a detailed log file. Upon failure, create debugging scripts.
Do not change environment variables directly. Instead, set them via
command line arguments. Set `AUTOTEST_PATH' to select the executables
to exercise. Each relative directory is expanded as build and source
directories relative to the top level of this distribution.
E.g., from within the build directory /tmp/foo-1.0, invoking this:
$ ./testsuite AUTOTEST_PATH=bin
is equivalent to the following, assuming the source directory is /src/foo-1.0:
PATH=/tmp/foo-1.0/bin:/src/foo-1.0/bin:$PATH ./testsuite
Operation modes:
-h, --help print the help message, then exit
-V, --version print version number, then exit
-c, --clean remove all the files this test suite might create and exit
-l, --list describes all the tests, or the selected TESTS
Execution tuning:
-C, --directory=DIR
change to directory DIR before starting
--color[=never|auto|always]
enable colored test results on terminal, or always
-j, --jobs[=N]
Allow N jobs at once; infinite jobs with no arg (default 1)
-k, --keywords=KEYWORDS
select the tests matching all the comma-separated KEYWORDS
multiple `-k' accumulate; prefixed `!' negates a KEYWORD
--recheck select all tests that failed or passed unexpectedly last time
-e, --errexit abort as soon as a test fails; implies --debug
-v, --verbose force more detailed output
default for debugging scripts
-d, --debug inhibit clean up and top-level logging
default for debugging scripts
-x, --trace enable tests shell tracing
Report bugs to .
其中最有用的一个参数值为-v
因此,我们可以手动模拟,进行ovsdb的单元测试:
./tests/testsuite -C tests -v AUTOTEST_PATH=utilities:vswitchd:ovsdb:vtep:tests::ovn/controller-vtep:ovn/northd:ovn/utilities:ovn/controller -k ovsdb
这样的话,会打印出单元测试的详细信息,我这里截取一部分:
1301. ovsdb-mutation.at:114: testing mutations on sets ...
./ovsdb-mutation.at:114: test-ovsdb parse-mutations \
'{"columns":
{"i": {"type": {"key": "integer", "min": 0, "max": "unlimited"}},
"r": {"type": {"key": "real", "min": 0, "max": "unlimited"}},
"b": {"type": {"key": "boolean", "min": 0, "max": "unlimited"}},
"s": {"type": {"key": "string", "min": 0, "max": "unlimited"}},
"u": {"type": {"key": "uuid", "min": 0, "max": "unlimited"}}}}' \
'[["i", "+=", 1]]' \
'[["i", "-=", 2]]' \
'[["i", "*=", 3]]' \
'[["i", "/=", 4]]' \
'[["i", "%=", 5]]' \
'[["i", "insert", ["set", [1, 2]]]]' \
'[["i", "delete", ["set", [1, 2, 3]]]]' \
'[["r", "+=", 1]]' \
'[["r", "-=", 2]]' \
'[["r", "*=", 3]]' \
'[["r", "/=", 4]]' \
'[["r", "insert", ["set", [1, 2]]]]' \
'[["r", "delete", ["set", [1, 2, 3]]]]' \
'[["b", "insert", ["set", [true]]]]' \
'[["b", "delete", ["set", [false]]]]' \
'[["s", "insert", ["set", ["a"]]]]' \
'[["s", "delete", ["set", ["a", "b"]]]]' \
'[["u", "insert",
["set", [["uuid", "b10d28f7-af18-4a67-9e78-2a6394516c59"]]]]]' \
'[["u", "delete",
["set", [["uuid", "b10d28f7-af18-4a67-9e78-2a6394516c59"],
["uuid", "9179ca6d-6d65-400a-b455-3ad92783a099"]]]]]' \
上面实际在调用tests目录下的test-ovsdb程序执行单元测试。
现在你可以用gdb来调试test-ovsdb了,结合单元测试里面的参数,边看代码边调试,这个程序其实测试了ovsdb的源代码的方方面面,基本上你读完了这个东西,对ovsdb也会有一个非常透彻的了解。这个时候在回过头去看ovsdb-server的代码,会感觉非常轻松。
这个就是我掌握的快速查看ovsdb源代码的方法。
最近写了一点注释,也提供了一些参考资料,想看的可以到这里来: https://github.com/lishuhuakai/ovs_reading