COMS W3156: Software Engineering, Fall 2001 Lecture #14: Implementation II, LDAP Janak J Parekh
Administrativia LDAP configured HW2 due now Design due in one week Requirements update pending (v1.2) –LDAP renaming –Missing some boolean operators –Something else? Webboard… –You are supposed to do the homework
Next class I’m debating
Today’s class Implementation, continued (testing) LDAP
From last class Conclusion: we need a compromise – highlight faults, while accepting that not all faults will be detected Black-box test cases first (specifications) Then, develop additional glass-box techniques (code)
Black-box module testing Goal: devise small number of test cases that cover most of the possibilities Every test case must be chosen to detect a previously undetected fault: don’t repeat Equivalence testing and boundary value analysis
Equivalence class testing Break down cases into equivalence classes Example: database with max 16,000 records –If it works for 251, it’ll probably work for 12,000 Define classes that need to be tested –Less than 1 record –From 1 to 16,000 records –More than 16,000 records
Boundary testing Take the equivalence classes to the next level –0 records –1 record –2 records –723 records –16,382 records –16,383 records –16,384 records
Boundary testing (II) Test both sides of the classes While the example referred to input specifications, can also boundary-test output cases Example: payroll –Test deductions between, and including, min and max deduction values, as well as beyond them –Devise test cases to get these results
Boundary testing (III) In general, for a range {R 1, R 2 }, 5 test cases: –Less than R 1 –Equal to R 1 –Greater than R 1, less than R 2 –Equal to R 2 –Greater than R 2 Need to start thinking this way
Functional testing Test on functionalities of module Step 1: determine functions of module Step 2: Devise test data for each low-level function Step 3: Determine higher-level functions (picture) This is hybrid black-box and glass-box
Functional testing (II) In practice, need to do functional analysis, since it’s not always so simple Often, cross-module functionality Object-oriented doesn’t help Difficult to resolve at times, but general principle remains sound
Glass-box testing Look at the source code, and design test cases from there Statement coverage Path coverage Branch coverage
Statement coverage Run a series of test cases in which every statement is executed at least once. Use a CASE tool to keep track of how many times each statement has been executed –Rational PureCoverage, which we do have, but we’re probably not going to use it Problem: no guarantee all outcomes of branches are tested (i.e. if clauses)
Branch coverage Run a series of tests to ensure all branches are tested at least once Tools such as Generic Coverage Tool (gct) Statement/branch coverage are structural tests
Path coverage Test all paths Challenge: reduce number of paths to be examined while still uncovering as many faults as possible –Restrict test cases to linear code sequences: identify set of points from which control may jump, and devise code sequences that begin at control flow and end at another control flow
All-definition-use-path Define each occurrence of a variable as a definition of the variable (int i=1) or use of the variable (y=i+5) Identify all paths between definition and use Set up a test case for each path Still theoretically 2 d paths (d = #branches) Can be shown that in real programs this is not reached
Dead code Sometimes programmers will have an “infeasible path” that cannot be reached given any input Statement coverage detects this
Complexity metrics Intuition suggests more complex code implies more bug-prone code Various metrics to determine complexity –LOC –McCabe’s measure of cyclomatic complexity # branches in the module Found to be reasonably accurate –Halstead utilizes a linear combination of several metrics (operators and operands) Problem: both Halstead and McCabe practically are linear with LOC
Code walkthroughs/inspections Works very, very well* Explaining your own code finds many faults Suggest you try it in a group environment Much cheaper than execution-based testing –Takes less time –Faults are detected earlier
Comparing testing mechanisms Brief conclusion: all are valid, but some work a bit better than others In some studies, it’s been shown that code reading was most effective at detecting “interface faults”, while black-box testing was most effective at finding “control faults” Conclusion: code walkthroughts/inspections work
Cleanroom Combine a number of different techniques, including incremental lifecycle Critical aspect: cannot compile a module until it passes inspection Has been successful for both small and large programs Metric: testing faults from time of compilation
Challenges of testing objects Can’t execution-test a class, only objects Information hiding and simple methods complicate things: need to call both setter and getter methods to test variable changes Need to test inherited methods! –Context may have changed: methods it may call may have been overridden
Miscellany Management: how much time and money to test? –Cost-benefit analysis –Reliability analysis: statistical determination of faults remaining When to rewrite? –Predetermine “maximum number of faults” Challenges –When, how to reuse code
LDAP Lightweight Directory Access Protocol Essentially a hierarchical (treelike) database –Attributes: Attribute-value pair –Objects: collection of Attributes (record) –Records are uniquely identified using the DN, or distinguished name Not XML, but you don’t need to talk the language: JNDI does the work
Distinguished name Unique name assigned to everything in the database Implicit hierarchy: “root” is the right part Comma (,) is delineator Utterly flexible “cn=Janak,ou=PSL,ou=CS,o=Columbia” “cn=Janak,dc=psl,dc=cs,dc=columbia,dc=e du”
Our LDAP database Designated as “o=softe” – it’s the root of the tree Three nodes (each have the root affixed): –ou=services –ou=actors –ou=states Each item under this must have its own DN
Entries in LDAP Every entry will have its own unique DN: the “identifier” will usually be a CN (Common Name) component of the DN “cn=A1,ou=services,dc=softe,dc=cs,dc=col umbia,dc=edu” “cn=johndoe,ou=actors,dc=softe,dc=cs,dc= columbia,dc=edu”
Schema Each entry can be one of any (millions) of types We’ve explicitly created three for you –Service –Actor –ActorState Names changed from requirements; will fix
Service Service reference ID: CN tag in DN: use your group ID Required: –ServerIP (string) –ServerPort (int) –ServerType (string): A or S Optional –WorldName –ServerExtensions
Actor Actor “name”/login id: CN tag in DN Required: –HP: int –XP: int –Gold: int –Password: String We’ll give you crypting code Optional: –ImageURL
ActorState CN in DN: unique identifier –Concatenate Actor, World, and Service –ac=actorname+wn=worldname+sv=servicename Required –LocationX: int –LocationY: int –Status: int –WorldInstance: int
JNDI Straightforward API, built into JDK 1.3 and higher Can do more than LDAP: DNS, etc. For LDAP, uses concept of directory context in which the operation will be done –ldap://softe.cs.columbia.edu:389/o=softe Once set, go ahead and do operation(s) Recitation!
JNDI Lookups getAttributes() method searches by (unique) DN –similar to lookup() but more powerful Returns Attributes object: collection of attribute-value pairs; you can “get” and “put”; like a Hashtable
JNDI Searches search() searches within a DN for all entries that match the Attributes set you provide Returns NamingEnumeration (subinterface of Enumeration) –Each entry in the Enumeration is a SearchResult, which you can convert toString() and then do a lookup
JNDI Lists list() finds all in the DN context Returns NamingEnumeration, consisting of NameClass pairs getName() method in this class
JNDI Writes Just like we can getAttributes(), we can… (re)bind() –Ok, so the parallel isn’t ideal –Name: DN –Object: null (Java can serialize to LDAP!) –Attributes: our good friend
JNDI Deletes unbind(); Must supply whole DN to it –Use search() if you don’t know what the full DN of the relevant object is Almost never throws exception, even if the record isn’t there –idempotent
JNDI Miscellany Name class –You don’t have to use this: it’s a bit more “civilized” way of dealing with DN’s, though –For the scope of this class, it’s acceptable just to use Strings for DN’s
Our permissions setup Services: readable by all, writeable only by those who have password Actors: read/write by password only ActorStates: read/write by password only Net effect –Client has no password, and no need of one –All servers will share the same DN and password (yes, logins are via DN too!)
What does this mean for you? Implementation/Testing –You now know what your testing plan will look like LDAP –You finally know all the details to use LDAP not only for your design, but also your implementation –Shouldn’t need a whole lot for the design –We give you code samples: adjust it to suit your needs