Live Hacking Before (Formal) Unit Testing¶
Initial Structure¶
$ tree
.
├── bin
│ └── CMakeLists.txt
├── CMakeLists.txt
├── src
│ └── userdb
│ └── CMakeLists.txt
└── tests
└── CMakeLists.txt
Talk about project plan
In memory
UserDB
. FeaturesLoad/store from/to file
Search
Iterate
User
¶
Talk
Database payload
ID is going to be primary key
⟶
UserDB
UserDB
¶
Create file from scratch (it is the class that we will be talking about)
void insert(const User& u) { /*not caring about duplicates*/ }
bin/userdb-write-binaryfile.cpp
¶
Talk
End goal: dump db into file format
Start with program
bin/userdb-write-binaryfile.cpp
Pull in
write-initial
Think about writing
Commandline parameter ⟶
filename
How?
⟶
db.write(filename);
Extend UserDB
To Write¶
In bin/userdb-write-binaryfile.cpp
Add
argv[1]
⟶ filenameAdd call
db.write(filename)
In src/userdb/userdb.{h,cpp}
, implement UserDB::write(const string&)
Write a chapter of method documentation!
Loop over
std::map
entries (using range basedfor
)Pull in
binary-user
open(... O_CREAT|O_TRUNC|O_WRONLY, 0666)
(assert
’ing that all is well)Mode 0666!!
Convert
User
toBinaryUser
Use
htons()
from<arpa/inet.h>
write()
, again onlyassert
’ing
Look into written file, using
od -c
Complete
bin/userdb-write-binaryfile.cpp
, to not write hardwired usersPull in
user-from-stdin
Finally, use
bin/userdb-write-binaryfile
to enter666, “Joerg”, “Huber”, “joerg@home.com”
42, “Caro”, “Huber”, “caro@home.com”
7, “Johanna”, “Huber”, “johanna@home.com”
Extend UserDB
To Read From File, And Iterate¶
Pull in
read-and-dump
intobin/userdb-read-binaryfile.cpp
Add to
CMakeLists.txt
Implement
UserDB::read()
Pull in
read-binary
into body ofread()
Compile, and see the iteration still not implemented
Pull
userdb-iterator
intouserdb.h
Pull
begin-end
intouserdb.h
Bug: Use “Faschingbauer” As Last Name¶
Create a new database,
666, “Joerg”, “Faschingbauer”, “joerg@home.com”
Dump it. See that
email
got overwritten.Write
tests/test-funny-overflow.cpp
. Suspecting the inmem DB to loose things (foolishly).Pull in
test-funny-overflow
into empty fileAdd to
CMakeLists.txt
Build
Implement
UserDB::find()
Run
Works ⟶ next test
Write
tests/test-funny-overflow-file.cpp
Copy
tests/test-funny-overflow.cpp
totests/test-funny-overflow-file.cpp
Pull in
temp-file
, right insidemain()
Find bug
Discuss: either change everything (errorhandling!)
⟶ no, lets just silently truncate
⟶ document that as a feature (i.e. modify the test to require “Faschingb”)
Wrap Up: What Do We Have?¶
Code base that works, somehow
How do we know?
⟶ we have two tests
$ for test in ./test-*; do [ -x $test ] && ( $test && echo "SUCCESS: $test" 1>&2 || echo "FAILURE: $test" 1>&2 ) done
SUCCESS: ./test-funny-overflow
SUCCESS: ./test-funny-overflow-file
test-funny-overflow
is actually testingUserDB::find()
Rename to
test-find