...
- Avoid using sleep() whenever possible, since it often leads to brittle tests. If you find that you have to wait for an event or wait for some work to be done by another thread, prefer latches or thread notifications to sleeps.
- Try to keep individual tests small, and only test one thing per test.
- Use mocking when you need to include a complicated service to satisfy dependencies. ONOS uses the EasyMock framework, version 3.4.
- Buck Bazel may choose to run multiple tests in the same Java virtual machine. If you use static variables in classes, be sure to reset them to known starting values before each test runs.
- Do not use local resources like files, ports, or IP Addresses in tests.
...
A basic test for each one of your constructors and a check for the values returned by data access methods should always be included.
Code Block | ||||
---|---|---|---|---|
| ||||
/** * Checks the construction of a FlowId object. */ @Test public void testConstruction() { final long flowIdValue = 7777L; final FlowId flowId = FlowId.valueOf(flowIdValue); assertThat(flowId, is(notNullValue())); assertThat(flowId.value(), is(flowIdValue)); } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
import org.onlab.junit.TestUtils; @Test public void testLeaderEvents() throws Exception { final ObjectiveTracker tracker = new ObjectiveTracker(); final SetMultimap<LinkKey, IntentId> intentsByLink = TestUtils.getField(tracker, "intentsByLink"); assertThat(intentsByLink.size(), is(0)); } |
...
Mocking
Mocking is a useful strategy for limiting the interaction between your code under test and other modules that are required to satisfy dependencies. There are several strategies that may be used for mocking, two that are used inside of ONOS are described here.
...
Code Block | ||||
---|---|---|---|---|
| ||||
private static class TestIntentCompilerError implements IntentCompiler<Intent> { @Override public List<Intent> compile(Intent intent, List<Intent> installable, Set<LinkResourceAllocations> resources) { throw new IntentCompilationException("Compilation always fails"); } } /** * Tests for proper behavior of installation of an intent that triggers * a compilation error. */ @Test public void errorIntentCompile() { final TestIntentCompilerError errorCompiler = new TestIntentCompilerError(); final IntentManager intentManager = new IntentManager(); final IntentExtensionService extensionService = intentManager; final IntentService intentService = intentManager; extensionService.registerCompiler(MyIntent.class, errorCompiler); MyIntent intent = new MyIntent(); // Invoke the error compiler intentService.submit(myIntent); } |
...
Hamcrest
Hamcrest is a powerful framework for defining matchers for data values in tests. ONOS uses version 1.3 of Hamcrest. Contributors are encouraged to learn about and use the Hamcrest framework, particularly when working with arrays and collections. Hamcrest also gives you the ability to write your own matchers, which will make your tests easier to read and easier to extend by other developers.
...
Code Block | ||||
---|---|---|---|---|
| ||||
/** * Hamcrest matcher to check that a selector contains a * Criterion with the specified type. */ public static final class CriterionExistsMatcher extends TypeSafeMatcher<TrafficSelector> { private final Criterion.Type type; /** * Constructs a matcher for the given criterion type. * * @param typeValue criterion type to match */ public CriterionExistsMatcher(Criterion.Type typeValue) { type = typeValue; } @Override public boolean matchesSafely(TrafficSelector selector) { final Set<Criterion> criteria = selector.criteria(); return notNullValue().matches(criteria) && hasSize(1).matches(criteria) && notNullValue().matches(selector.getCriterion(type)); } @Override public void describeTo(Description description) { description.appendText("a criterion with type \" "). appendText(type.toString()). appendText("\""); } } /** * Creates a criterion type matcher. Returns a matcher * for a criterion with the given type. * * @param type type of Criterion to match * @return Matcher object */ @Factory public static Matcher<TrafficSelector> hasCriterionWithType(Criterion.Type type) { return new CriterionExistsMatcher(type); } /** * Tests the builder functions that add specific criteria. */ @Test public void testCriteriaCreation() { TrafficSelector selector; selector = DefaultTrafficSelector.builder() .matchInport(PortNumber.portNumber(11)).build(); assertThat(selector, hasCriterionWithType(Type.IN_PORT)); } |
...
Add library for Unit Test
If you are using a library for Unit Test other than the above, please add the library to the build path. You can modify the lib/deps.json
file where we keep track of external libraries and then run “onos-lib-gen” tool to update the lib/BUCK file. :
Code Block | ||||
---|---|---|---|---|
| ||||
vi lib/deps.json |
Code Block | ||
---|---|---|
| ||
{ "libraries": { ・・・ , "TEST": [ "[new library name]", "junit", "easymock", "hamcrest-all", "hamcrest-optional", "guava-testlib", "//utils/junit:onlab-junit" ], ・・・ }, "artifacts": { ・・・ "jsch":"mvn:com.jcraft:jsch:0.1.53", "[new library name]":"mvn:[new library path]:[new library version]", "junit":"mvn:junit:junit:4.12", "junit-dep":"mvn:junit:junit:4.10", ・・・ } } |
...and then run onos-lib-gen
tool to re-generate the Bazel workspace file.
Code Block | ||||
---|---|---|---|---|
| ||||
tools/build/onos-lib-gen |
...
Home : Contributing to the ONOS Codebase
...
...