Jian Li
Committed by Gerrit Code Review

[ONOS-2225] Add unit test for Flow Objectives REST API

This commits add unit tests for Flow Objective REST API.
The corresponding REST API implementation can be referred to
e9ac2c50.

Change-Id: I018fdafe103b3eb14e06c162c47093a11d660b26
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
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 + */
16 +package org.onosproject.rest;
17 +
18 +import com.eclipsesource.json.JsonObject;
19 +import com.sun.jersey.api.client.ClientResponse;
20 +import com.sun.jersey.api.client.WebResource;
21 +import org.hamcrest.Matchers;
22 +import org.junit.After;
23 +import org.junit.Before;
24 +import org.junit.Test;
25 +import org.onlab.osgi.ServiceDirectory;
26 +import org.onlab.osgi.TestServiceDirectory;
27 +import org.onlab.rest.BaseResource;
28 +import org.onosproject.codec.CodecService;
29 +import org.onosproject.codec.impl.CodecManager;
30 +import org.onosproject.core.CoreService;
31 +import org.onosproject.net.NetTestTools;
32 +import org.onosproject.net.flowobjective.FlowObjectiveService;
33 +import org.onosproject.rest.resources.CoreWebApplication;
34 +
35 +import javax.ws.rs.core.MediaType;
36 +import java.io.InputStream;
37 +import java.net.HttpURLConnection;
38 +
39 +import static org.easymock.EasyMock.anyObject;
40 +import static org.easymock.EasyMock.anyShort;
41 +import static org.easymock.EasyMock.createMock;
42 +import static org.easymock.EasyMock.expect;
43 +import static org.easymock.EasyMock.expectLastCall;
44 +import static org.easymock.EasyMock.replay;
45 +import static org.easymock.EasyMock.verify;
46 +import static org.hamcrest.Matchers.hasSize;
47 +import static org.hamcrest.Matchers.is;
48 +import static org.hamcrest.Matchers.notNullValue;
49 +import static org.junit.Assert.assertThat;
50 +import static org.onosproject.net.NetTestTools.APP_ID;
51 +
52 +/**
53 + * Unit tests for flow objectives REST APIs.
54 + */
55 +public class FlowObjectiveResourceTest extends ResourceTest {
56 + final FlowObjectiveService mockFlowObjectiveService = createMock(FlowObjectiveService.class);
57 + CoreService mockCoreService = createMock(CoreService.class);
58 + public static final String REST_APP_ID = "org.onosproject.rest";
59 +
60 + public FlowObjectiveResourceTest() {
61 + super(CoreWebApplication.class);
62 + }
63 +
64 + /**
65 + * Sets up the global values for all the tests.
66 + */
67 + @Before
68 + public void setUpTest() {
69 + // Mock Core Service
70 + expect(mockCoreService.getAppId(anyShort()))
71 + .andReturn(NetTestTools.APP_ID).anyTimes();
72 + expect(mockCoreService.registerApplication(REST_APP_ID))
73 + .andReturn(APP_ID).anyTimes();
74 + replay(mockCoreService);
75 +
76 + // Register the services needed for the test
77 + final CodecManager codecService = new CodecManager();
78 + codecService.activate();
79 + ServiceDirectory testDirectory =
80 + new TestServiceDirectory()
81 + .add(FlowObjectiveService.class, mockFlowObjectiveService)
82 + .add(CodecService.class, codecService)
83 + .add(CoreService.class, mockCoreService);
84 +
85 + BaseResource.setServiceDirectory(testDirectory);
86 + }
87 +
88 + /**
89 + * Cleans up and verifies the mocks.
90 + */
91 + @After
92 + public void tearDownTest() {
93 + verify(mockFlowObjectiveService);
94 + verify(mockCoreService);
95 + }
96 +
97 + /**
98 + * Tests creating a filtering objective with POST.
99 + */
100 + @Test
101 + public void testFilteringObjectivePost() {
102 + mockFlowObjectiveService.filter(anyObject(), anyObject());
103 + prepareService();
104 + testObjectiveCreation("post-filter-objective.json", "of:0000000000000001", "filter");
105 + }
106 +
107 + /**
108 + * Tests creating a forwarding objective with POST.
109 + */
110 + @Test
111 + public void testForwardingObjectivePost() {
112 + mockFlowObjectiveService.forward(anyObject(), anyObject());
113 + prepareService();
114 + testObjectiveCreation("post-forward-objective.json", "of:0000000000000001", "forward");
115 + }
116 +
117 + /**
118 + * Tests creating a next objective with POST.
119 + */
120 + @Test
121 + public void testNextObjectivePost() {
122 + mockFlowObjectiveService.next(anyObject(), anyObject());
123 + prepareService();
124 + testObjectiveCreation("post-next-objective.json", "of:0000000000000001", "next");
125 + }
126 +
127 + /**
128 + * Tests obtaining a global unique nextId with GET.
129 + */
130 + @Test
131 + public void testNextId() {
132 + expect(mockFlowObjectiveService.allocateNextId()).andReturn(10).anyTimes();
133 + prepareService();
134 +
135 + WebResource rs = resource();
136 + final String response = rs.path("flowobjectives/next").get(String.class);
137 + final JsonObject result = JsonObject.readFrom(response);
138 + assertThat(result, notNullValue());
139 +
140 + assertThat(result.names(), hasSize(1));
141 + assertThat(result.names().get(0), is("nextId"));
142 + final int jsonNextId = result.get("nextId").asInt();
143 + assertThat(jsonNextId, is(10));
144 + }
145 +
146 + private void prepareService() {
147 + expectLastCall();
148 + replay(mockFlowObjectiveService);
149 + }
150 +
151 + /**
152 + * A base class for testing various objective creation.
153 + *
154 + * @param jsonFile json file path
155 + * @param deviceId device id in string format
156 + * @param method objective method
157 + */
158 + private void testObjectiveCreation(String jsonFile, String deviceId, String method) {
159 + WebResource rs = resource();
160 + InputStream jsonStream = FlowsResourceTest.class
161 + .getResourceAsStream(jsonFile);
162 +
163 + StringBuilder sb = new StringBuilder();
164 + sb.append("flowobjectives");
165 + sb.append("/");
166 + sb.append(deviceId);
167 + sb.append("/");
168 + sb.append(method);
169 +
170 + ClientResponse response = rs.path(sb.toString())
171 + .type(MediaType.APPLICATION_JSON_TYPE)
172 + .post(ClientResponse.class, jsonStream);
173 + assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
174 + String location = response.getLocation().getPath();
175 + assertThat(location, Matchers.startsWith("/" + sb.toString()));
176 + }
177 +}
1 +{
2 + "priority": 1,
3 + "isPermanent": false,
4 + "deviceId": "of:0000000000000001",
5 + "timeout": 1,
6 + "type": "PERMIT",
7 + "operation": "ADD",
8 + "conditions": [
9 + {
10 + "type": "IN_PORT",
11 + "port": 23
12 + }
13 + ],
14 + "meta": {
15 + "instructions": [
16 + {
17 + "type": "OUTPUT",
18 + "port": -3
19 + },
20 + {
21 + "type": "DROP"
22 + }
23 + ]
24 + }
25 +}
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "priority": 1,
3 + "isPermanent": false,
4 + "timeout": 1,
5 + "flag": "SPECIFIC",
6 + "operation": "ADD",
7 + "selector": {
8 + "criteria": [
9 + {
10 + "type": "ETH_TYPE",
11 + "ethType": "0x806"
12 + }
13 + ]
14 + },
15 + "treatment":
16 + {
17 + "instructions":
18 + [
19 + {"type":"OUTPUT","port":-3},
20 + {"type":"DROP"}
21 + ]
22 + }
23 +}
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "id": 1,
3 + "type": "FAILOVER",
4 + "operation": "ADD",
5 + "treatments": [
6 + {
7 + "instructions": [
8 + {
9 + "type": "OUTPUT",
10 + "port": -3
11 + },
12 + {
13 + "type": "DROP"
14 + }
15 + ]
16 + }
17 + ],
18 + "meta": {
19 + "criteria": [
20 + {
21 + "type": "IN_PORT",
22 + "port": 23
23 + }
24 + ]
25 + }
26 +}
...\ No newline at end of file ...\ No newline at end of file