blob: 2ae87fb71be463e394ba4ef2c97aefae645a9176 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present Open Networking Laboratory
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.intent;
Brian O'Connorf3d06162014-10-02 15:54:12 -070017
Brian O'Connorcb900f42014-10-07 21:55:33 -070018import org.junit.After;
19import org.junit.Before;
20import org.junit.Test;
Brian O'Connorf3d06162014-10-02 15:54:12 -070021
Brian O'Connor64a0369d2015-02-20 22:02:59 -080022import java.util.ArrayList;
23import java.util.Arrays;
Brian O'Connor64a0369d2015-02-20 22:02:59 -080024import java.util.Collections;
25import java.util.Iterator;
26import java.util.List;
Brian O'Connor64a0369d2015-02-20 22:02:59 -080027
28import static org.junit.Assert.*;
29import static org.onosproject.net.intent.IntentEvent.Type.*;
30
Brian O'Connorf3d06162014-10-02 15:54:12 -070031/**
32 * Suite of tests for the intent service contract.
33 */
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070034public class IntentServiceTest extends AbstractIntentTest {
Brian O'Connorf3d06162014-10-02 15:54:12 -070035
Brian O'Connor520c0522014-11-23 23:50:47 -080036 public static final int IID = 123;
37 public static final int INSTALLABLE_IID = 234;
Brian O'Connorf3d06162014-10-02 15:54:12 -070038
39 protected static final int GRACE_MS = 500; // millis
40
41 protected TestableIntentService service;
42 protected TestListener listener = new TestListener();
43
44 @Before
45 public void setUp() {
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070046 super.setUp();
Brian O'Connorf3d06162014-10-02 15:54:12 -070047 service = createIntentService();
48 service.addListener(listener);
49 }
50
51 @After
52 public void tearDown() {
53 service.removeListener(listener);
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070054 super.tearDown();
Brian O'Connorf3d06162014-10-02 15:54:12 -070055 }
56
57 /**
58 * Creates a service instance appropriately instrumented for testing.
59 *
60 * @return testable intent service
61 */
62 protected TestableIntentService createIntentService() {
63 return new FakeIntentManager();
64 }
65
66 @Test
67 public void basics() {
68 // Make sure there are no intents
Brian O'Connor66630c82014-10-02 21:08:19 -070069 assertEquals("incorrect intent count", 0, service.getIntentCount());
Brian O'Connorf3d06162014-10-02 15:54:12 -070070
71 // Register a compiler and an installer both setup for success.
72 service.registerCompiler(TestIntent.class, new TestCompiler(new TestInstallableIntent(INSTALLABLE_IID)));
Brian O'Connorf3d06162014-10-02 15:54:12 -070073
74 final Intent intent = new TestIntent(IID);
75 service.submit(intent);
76
77 // Allow a small window of time until the intent is in the expected state
Sho SHIMIZU74626412015-09-11 11:46:27 -070078 TestTools.assertAfter(GRACE_MS, () ->
79 assertEquals("incorrect intent state", IntentState.INSTALLED, service.getIntentState(intent.key())));
Brian O'Connorf3d06162014-10-02 15:54:12 -070080
81 // Make sure that all expected events have been emitted
Brian O'Connor7a71d5d2014-12-02 00:12:27 -080082 validateEvents(intent, INSTALL_REQ, INSTALLED);
Brian O'Connorf3d06162014-10-02 15:54:12 -070083
84 // Make sure there is just one intent (and is ours)
Brian O'Connor66630c82014-10-02 21:08:19 -070085 assertEquals("incorrect intent count", 1, service.getIntentCount());
Brian O'Connorf3d06162014-10-02 15:54:12 -070086
87 // Reset the listener events
88 listener.events.clear();
89
90 // Now withdraw the intent
91 service.withdraw(intent);
92
93 // Allow a small window of time until the event is in the expected state
Sho SHIMIZU74626412015-09-11 11:46:27 -070094 TestTools.assertAfter(GRACE_MS, () ->
95 assertEquals("incorrect intent state", IntentState.WITHDRAWN, service.getIntentState(intent.key())));
Brian O'Connorf3d06162014-10-02 15:54:12 -070096
97 // Make sure that all expected events have been emitted
tom85258ee2014-10-07 00:10:02 -070098 validateEvents(intent, WITHDRAWN);
Brian O'Connorf3d06162014-10-02 15:54:12 -070099
100 // TODO: discuss what is the fate of intents after they have been withdrawn
101 // Make sure that the intent is no longer in the system
102// assertEquals("incorrect intent count", 0, service.getIntents().size());
tom85258ee2014-10-07 00:10:02 -0700103// assertNull("intent should not be found", service.getIntent(intent.id()));
104// assertNull("intent state should not be found", service.getIntentState(intent.id()));
Brian O'Connorf3d06162014-10-02 15:54:12 -0700105 }
106
107 @Test
108 public void failedCompilation() {
109 // Register a compiler programmed for success
110 service.registerCompiler(TestIntent.class, new TestCompiler(true));
111
112 // Submit an intent
113 final Intent intent = new TestIntent(IID);
114 service.submit(intent);
115
116 // Allow a small window of time until the intent is in the expected state
Sho SHIMIZU74626412015-09-11 11:46:27 -0700117 TestTools.assertAfter(GRACE_MS, () ->
118 assertEquals("incorrect intent state", IntentState.FAILED, service.getIntentState(intent.key())));
Brian O'Connorf3d06162014-10-02 15:54:12 -0700119
120 // Make sure that all expected events have been emitted
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800121 validateEvents(intent, INSTALL_REQ, FAILED);
Brian O'Connorf3d06162014-10-02 15:54:12 -0700122 }
123
Brian O'Connorf3d06162014-10-02 15:54:12 -0700124 /**
125 * Validates that the test event listener has received the following events
126 * for the specified intent. Events received for other intents will not be
127 * considered.
128 *
129 * @param intent intent subject
tom85258ee2014-10-07 00:10:02 -0700130 * @param types list of event types for which events are expected
Brian O'Connorf3d06162014-10-02 15:54:12 -0700131 */
tom85258ee2014-10-07 00:10:02 -0700132 protected void validateEvents(Intent intent, IntentEvent.Type... types) {
Brian O'Connorf3d06162014-10-02 15:54:12 -0700133 Iterator<IntentEvent> events = listener.events.iterator();
tom85258ee2014-10-07 00:10:02 -0700134 for (IntentEvent.Type type : types) {
Brian O'Connorf3d06162014-10-02 15:54:12 -0700135 IntentEvent event = events.hasNext() ? events.next() : null;
136 if (event == null) {
tom85258ee2014-10-07 00:10:02 -0700137 fail("expected event not found: " + type);
138 } else if (intent.equals(event.subject())) {
139 assertEquals("incorrect state", type, event.type());
Brian O'Connorf3d06162014-10-02 15:54:12 -0700140 }
141 }
142
143 // Remainder of events should not apply to this intent; make sure.
144 while (events.hasNext()) {
145 assertFalse("unexpected event for intent",
tom85258ee2014-10-07 00:10:02 -0700146 intent.equals(events.next().subject()));
Brian O'Connorf3d06162014-10-02 15:54:12 -0700147 }
148 }
149
150 @Test
151 public void compilerBasics() {
152 // Make sure there are no compilers
153 assertEquals("incorrect compiler count", 0, service.getCompilers().size());
154
155 // Add a compiler and make sure that it appears in the map
156 IntentCompiler<TestIntent> compiler = new TestCompiler(false);
157 service.registerCompiler(TestIntent.class, compiler);
158 assertEquals("incorrect compiler", compiler,
159 service.getCompilers().get(TestIntent.class));
160
161 // Remove the same and make sure that it no longer appears in the map
162 service.unregisterCompiler(TestIntent.class);
163 assertNull("compiler should not be registered",
164 service.getCompilers().get(TestIntent.class));
165 }
166
167 @Test
Brian O'Connorf3d06162014-10-02 15:54:12 -0700168 public void implicitRegistration() {
169 // Add a compiler and make sure that it appears in the map
170 IntentCompiler<TestIntent> compiler = new TestCompiler(new TestSubclassInstallableIntent(INSTALLABLE_IID));
171 service.registerCompiler(TestIntent.class, compiler);
172 assertEquals("incorrect compiler", compiler,
173 service.getCompilers().get(TestIntent.class));
174
Brian O'Connorf3d06162014-10-02 15:54:12 -0700175 // Submit an intent which is a subclass of the one we registered
176 final Intent intent = new TestSubclassIntent(IID);
177 service.submit(intent);
178
179 // Allow some time for the intent to be compiled and installed
Sho SHIMIZU74626412015-09-11 11:46:27 -0700180 TestTools.assertAfter(GRACE_MS, () ->
181 assertEquals("incorrect intent state", IntentState.INSTALLED, service.getIntentState(intent.key())));
Brian O'Connorf3d06162014-10-02 15:54:12 -0700182
183 // Make sure that now we have an implicit registration of the compiler
184 // under the intent subclass
185 assertEquals("incorrect compiler", compiler,
186 service.getCompilers().get(TestSubclassIntent.class));
187
Brian O'Connorf3d06162014-10-02 15:54:12 -0700188 // TODO: discuss whether or if implicit registration should require implicit unregistration
189 // perhaps unregister by compiler or installer itself, rather than by class would be better
190 }
191
192
193 // Fixture to track emitted intent events
Brian O'Connor66630c82014-10-02 21:08:19 -0700194 protected class TestListener implements IntentListener {
Brian O'Connorf3d06162014-10-02 15:54:12 -0700195 final List<IntentEvent> events = new ArrayList<>();
196
197 @Override
198 public void event(IntentEvent event) {
199 events.add(event);
200 }
201 }
202
203 // Controllable compiler
204 private class TestCompiler implements IntentCompiler<TestIntent> {
205 private final boolean fail;
206 private final List<Intent> result;
207
208 TestCompiler(boolean fail) {
209 this.fail = fail;
210 this.result = Collections.emptyList();
211 }
212
213 TestCompiler(Intent... result) {
214 this.fail = false;
215 this.result = Arrays.asList(result);
216 }
217
218 @Override
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800219 public List<Intent> compile(TestIntent intent, List<Intent> installable) {
Brian O'Connorf3d06162014-10-02 15:54:12 -0700220 if (fail) {
221 throw new IntentException("compile failed by design");
222 }
223 List<Intent> compiled = new ArrayList<>(result);
224 return compiled;
225 }
226 }
Brian O'Connorf3d06162014-10-02 15:54:12 -0700227}