Index of /~billard/se/cs4320/ex7
Name Last modified Size Description
Parent Directory 20-Apr-2008 08:49 -
black 19-May-2009 09:03 7k
black.c 19-May-2009 09:03 1k
btree 19-May-2009 09:03 43k
btree.c 19-May-2009 09:03 14k
btree.dat 19-May-2009 09:03 1k
print.bat 19-May-2009 09:03 1k
printdoc.bat 19-May-2009 09:03 1k
CS 4320 Software Testing and QA: Ex7 UNIT TEST
==============================================
Platform: UNIX or PC
Given: B-tree written in C
Goals: Black box test a Btree function
a. Remember Binary Search Trees (BST) from CS 3240 Data Structures:
http://www.sci.csueastbay.edu/~billard/cs3240/node19.html
The key point is: at any given node, the keys to the LEFT are LESS than the
current key, and the keys to the RIGHT are GREATER.
This makes it easy to find a key - just go LEFT or RIGHT as necessary until the key
is found, or the search falls off the tree.
If the tree is balanced, it only takes O(log n) performance.
Now, here is a B-tree:
[j]
__________|__________
/ \
[c,f] [m,r]
______|______ ________|________
/ / \ / / \
[a,b] [d,e] [g,i] [k,l] [n,p] [s,t,u,x]
"B" tree does not mean "Binary", it means "Balanced".
In fact, a B-tree can have many keys per node (or page), and does not have just
LEFT and RIGHT children. If a node has 2 keys, then it will have 3 children.
Look at the [m,r] node: the first pointer points to the [k,l] node, whose keys are
are LESS than "m". The second pointer points to the [n,p] node, whose keys are
GREATER than "m" but LESS than "r". The third, and final, pointer points to
the [s,t,u,x] node, whose keys are GREATER than "r".
How to find the key "p"? Starting from the root, "p" is GREATER than "j", so
chase the second pointer to [m,r]. Key "p" is GREATER than "m" but LESS than "r",
so again chase the second pointer to [n,p]. The page is searched and "p" is found.
This is just like a BST, but nodes have more keys and more pointers. Also note that
the keys within a node are SORTED in ascending order.
If you really want more details, read the following (especially pages 78..80, 92..95]:
http://www.sci.csueastbay.edu/~billard/cs3240/node20.html
b. Now lets look at the implementation of a B-tree node:
typedef char Key_type;
#define MAX 4
typedef struct node_tag {
int count;
Key_type key[MAX+1];
struct node_tag *branch[MAX+1];
} Node_type;
"count" is the number of keys in the node (count+1 is the number of pointers).
The "key" array holds the actual keys and, likewise, the "branch" array holds
the pointers to children nodes.
Here is a picture of part of the B-tree illustrated above:
root
|
v
+---+
| 1 | count
+---+---+---+---+---+
| | j | | | | key[]
+---+---+---+---+---+
|p_1|p_2| | | | branch[]
+---+---+---+---+---+
0 1 2 3 4
where p_1, p_2 are pointers to these children nodes:
p_1
|
v
+---+
| 2 | count
+---+---+---+---+---+
| | c | f | | | key[]
+---+---+---+---+---+
|p_3|p_4|p_5| | | branch[]
+---+---+---+---+---+
0 1 2 3 4
p_2
|
v
+---+
| 2 | count
+---+---+---+---+---+
| | m | r | | | key[]
+---+---+---+---+---+
|p_6|p_7|p_8| | | branch[]
+---+---+---+---+---+
0 1 2 3 4
where p_3 points to the [a,b] node, p_4 points to the [d,e] node, etc.
Note that key[0] is never used. The idea is to keep two parallel arrays but
there's always one more branch than key.
In summary, branch[0] points to all keys LESS than key[1], branch[1] points
to all keys GREATER than key[1] but LESS than key[2], etc.
c. given: btree.c, btree.dat
btree.dat:
D 0
i a
p
i g
p
i f
p
i b
p
i k
p
q
The "i" stands for insert, and "p" stands for print.
% gcc -o btree btree.c
% btree btree.dat
Collect buggy output: btree btree.dat >btree1.out
Note the correct final result should be:
L
0 [f]
___|___
/ \
1 [a,b] [g,k]
d. black box test a function
You are given black.c which contains a copy of the function PushIn in btree.c, an almost empty main,
and a PrintPage function to display a page.
Note that main mallocs a pointer to a Node_type.
Be sure to initialize the count for this empty node.
The main should then call PushIn (and PrintPage) four times to insert the letters:
a, g, f, b
The xr pointer can just be NULL.
The value of k should be appropriate so a, g, f, b get
inserted into proper order: a, b, f, g
Note that PushIn expects the insertion location to be one more than k.
For example, the first insert (a) uses k=0, and the page should look like:
p
|
v
+---+
| 1 | count
+---+---+---+---+---+
| | a | | | | key[]
+---+---+---+---+---+
| | | | | | branch[]
+---+---+---+---+---+
0 1 2 3 4
After the second insert (g), the page should look like:
p
|
v
+---+
| 2 | count
+---+---+---+---+---+
| | a | g | | | key[]
+---+---+---+---+---+
| | | | | | branch[]
+---+---+---+---+---+
0 1 2 3 4
Think of the input chars as arriving one-at-a-time, and insert appropriately.
You're building a black box test using your main. The main tries to mimic the
real software, and typically data arrives one-at-a-time, especially for interactive
software.
The PushIn function assigns a char to the array at position k+1.
If the position k+1 is not empty, it pushes the necessary values to the right.
Remember: You (in the main function) determine which position an incoming char should be
placed at in order to achieve the required sorting order.
Since all inputs are serial (one-at-a-time), the value of k should be determined based
on which chars (and at which location) already exist in the array.
When you're done inserting, the page "should" have "a b f g".
Run the program
% black >black.out
Examine the output.
What is wrong? Can you find a bug in PushIn?
If yes, fix btree.c:
% btree btree.dat >btree2.out
e. Fill-out report.txt
Be sure to include information about bugs and your fixes.
ONLINE students: just submit black.c, black.out (with your report included)
f. Project Notebook:
README
report.txt
btree1.out [the original bad output]
btree2.out [good output]
black.c
black.out
btree.c