240 likes | 255 Views
Learn about the innovative in vivo testing approach, its implementation framework, and how it addresses testing challenges in deployment environments. Explore case studies on caching systems and the benefits compared to traditional unit testing.
E N D
The In Vivo Testing Approach Christian Murphy, Gail Kaiser, Ian Vo, Matt Chu Columbia University
Problem Statement • It is infeasible to fully test a large system prior to deployment considering: • different runtime environments • different configuration options • different patterns of usage • This problem may be compounded by moving apps from single-CPU machines to multi-core processors
Our Solution • Continually test applications executing in the field (in vivo) as opposed to only testing in the development environment (in vitro) • Conduct the tests in the context of the running application • Do so without affecting the system’s users
int main ( ) { ... ... ... foo(x); int main ( ) { ... ... ... foo(x); test_foo(x); ... ... }
Contributions • A new testing approach called in vivo testing designed to execute tests in the deployment environment • A new type of tests called in vivo tests • An implementation framework called Invite
Related Work • Perpetual testing [Clarke SAS’00] • Skoll [Memon ICSE’04] • Gamma [Orso ISSTA’02] • CBI [Liblit PLDI’03] • Distributed In Vivo Testing [Chu ICST’08]
Number of items in the cache Their size (in bytes) Should only be incremented within “if” block Example of Defect: Cache private int numItems = 0, currSize = 0; private int maxCapacity = 1024; // in bytes public int getNumItems() { return numItems; } public boolean addItem(CacheItem i) throws ... { numItems++; add(i); currSize += i.size; return true; } Maximum capacity if (currSize + i.size < maxCapacity) { } else { return false; }
Insufficient Unit Test public void testAddItem() { Cache c = new Cache(); assert(c.addItem(new CacheItem())) assert(c.getNumItems() == 1); assert(c.addItem(new CacheItem())) assert(c.getNumItems() == 2); } 1. Assumes an empty/new cache 2. Doesn’t take into account various states that the cache can be in
Defects Targeted • Unit tests that make incomplete assumptions about the state of objects in the application • Possible field configurations that were not tested in the lab • A legal user action that puts the system in an unexpected state • A sequence of unanticipated user actions that breaks the system • Defects that only appear intermittently
Applications Targeted • Applications that produce calculations or results that may not be obviously wrong • “Non-testable programs” • Simulations • Applications in which exta-functional behavior may be wrong even if output is correct • Caching systems • Scheduling of tasks
In Vivo Testing: Process • Create test code (using existing unit tests or new In Vivo tests) • Instrument application using Invite testing framework • Configure framework • Deploy/execute application in the field
Run a test? Rest of program continues Stop Fork Model of Execution Function is about to be executed Execute function NO Yes Run test Create sandbox
Writing In Vivo Tests /* Method to be tested */ public boolean addItem(CacheItem i) { . . . } /* JUnit style test */ public void testAddItem() { Cache c = new Cache(); if (c.addItem(new CacheItem())) assert (c.getNumItems() == 1); } In Vivo boolean CacheItem i) { this; int oldNumItems = getNumItems(); i)) return oldNumItems+1; else return true;
Instrumentation /* Method to be tested */ public boolean __addItem(CacheItem i) { . . . } /* In Vivo style test */ public boolean testAddItem(CacheItem i) { ... } public boolean addItem(CacheItem i) { if (Invite.runTest(“Cache.addItem”)) { Invite.createSandboxAndFork(); if (Invite.isTestProcess()) { if (testAddItem(i) == false) Invite.fail(); else Invite.succeed(); Invite.destroySandboxAndExit(); } } return __addItem(i); }
Configuration • Each instrumented method has a set probability ρwith which its test(s) will run • To avoid bottlenecks, can also configure: • Maximum allowed performance overhead • Maximum number of simultaneous tests • Also, what action to take when a test fails
Case Studies • Applied testing approach to two caching systems • OSCache 2.1.1 • Apache JCS 1.3 • Both had known defects that were found by users (no corresponding unit tests for these defects) • Goal: demonstrate that “traditional” unit tests would miss these but In Vivo testing would detect them
Experimental Setup • An undergraduate student created unit tests for the methods that contained the defects • These tests passed in “development” • Student was then asked to convert the unit tests to In Vivo tests • Driver created to simulate real usage in a “deployment environment”
Discussion • In Vivo testing revealed all defects, even though unit testing did not • Some defects only appeared in certain states, e.g. when the cache was at full capacity • These are the very types of defects that In Vivo testing is targeted at • However, the approach depends heavily on the quality of the tests themselves
Performance Evaluation • We instrumented three C and two Java applications with the framework and varied the value ρ(probability that a test is run) • Applications were run with real-world inputs on a dual-core 3GHz server with 1GB RAM • No restraints were placed on maximum allowable overhead or simultaneous tests
Experimental Results Time (seconds) 0% 25% 50% 75% 100% percent of function calls resulting in tests
Discussion • Percent overhead is not a meaningful metric since it depends on the number of tests run • More tests = more overhead • Short-running programs with lots of tests will have significantly more “overhead” than long-running programs • For C, the overhead was 1.5ms per test • For Java, around 5.5ms per test
Future Work • Ensure that test does not affect the external system state (database, network, etc.) • Adjust frequency of test execution based on context or resource availability (CPU usage, number of threads, etc.) • Apply approach to certain domains, e.g. security testing
Conclusion • We have presented a new testing approach called in vivo testing designed to execute tests in the deployment environment • We have also presented an implementation framework called Invite • In Vivo testing is an effective technique at detecting defects not caught in the lab
The In Vivo Testing Approach Christian Murphy, Gail Kaiser, Ian Vo, Matt Chu Columbia University