blob: 04cf638e88ee5c1828dd1afb8ffcc75762a130a2 [file] [log] [blame]
Jian Li2d3a1d12017-04-05 00:56:54 +09001/*
Brian O'Connorce2a03d2017-08-03 19:21:03 -07002 * Copyright 2017-present Open Networking Foundation
Jian Li2d3a1d12017-04-05 00:56:54 +09003 *
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 */
Jian Li2e818b02017-04-12 19:28:30 +090016package org.onosproject.mapping.codec;
Jian Li2d3a1d12017-04-05 00:56:54 +090017
18import com.fasterxml.jackson.databind.JsonNode;
Jian Li2d3a1d12017-04-05 00:56:54 +090019import com.fasterxml.jackson.databind.node.ObjectNode;
20import org.hamcrest.Description;
21import org.hamcrest.TypeSafeDiagnosingMatcher;
22import org.junit.After;
23import org.junit.Before;
24import org.junit.Test;
25import org.onlab.packet.IpPrefix;
26import org.onosproject.codec.CodecContext;
Jian Li2d3a1d12017-04-05 00:56:54 +090027import org.onosproject.codec.JsonCodec;
28import org.onosproject.codec.impl.CodecManager;
29import org.onosproject.mapping.DefaultMappingTreatment;
30import org.onosproject.mapping.DefaultMappingValue;
31import org.onosproject.mapping.MappingTreatment;
32import org.onosproject.mapping.MappingValue;
33import org.onosproject.mapping.actions.MappingAction;
34import org.onosproject.mapping.actions.MappingActions;
35import org.onosproject.mapping.addresses.MappingAddress;
36import org.onosproject.mapping.addresses.MappingAddresses;
37import org.onosproject.mapping.instructions.MappingInstruction;
38import org.onosproject.mapping.instructions.MappingInstructions;
Jian Li2e818b02017-04-12 19:28:30 +090039import org.onosproject.mapping.MappingCodecRegistrator;
Jian Li2d3a1d12017-04-05 00:56:54 +090040
41import java.io.IOException;
42import java.io.InputStream;
43
44import static org.hamcrest.MatcherAssert.assertThat;
45import static org.hamcrest.Matchers.is;
46import static org.hamcrest.Matchers.notNullValue;
47
48/**
49 * Unit tests for MappingValueCodec.
50 */
51public class MappingValueCodecTest {
52
53 private static final String TREATMENTS = "treatments";
54 private static final String ADDRESS = "address";
55 private static final String IPV4_STRING = "1.2.3.4";
56 private static final String PORT_STRING = "32";
57 private static final IpPrefix IPV4_PREFIX =
58 IpPrefix.valueOf(IPV4_STRING + "/" + PORT_STRING);
59
60 private static final int UNICAST_WEIGHT = 1;
61 private static final int UNICAST_PRIORITY = 1;
62 private static final int MULTICAST_WEIGHT = 2;
63 private static final int MULTICAST_PRIORITY = 2;
64
65 private CodecContext context;
66 private JsonCodec<MappingValue> valueCodec;
67 private MappingCodecRegistrator registrator;
68
69 /**
70 * Sets up for each test.
71 * Creates a context and fetches the mapping value codec.
72 */
73 @Before
74 public void setUp() {
75 CodecManager manager = new CodecManager();
76 registrator = new MappingCodecRegistrator();
77 registrator.codecService = manager;
78 registrator.activate();
79
Jian Lifa69be62017-04-05 16:00:10 +090080 context = new MappingCodecContextAdapter(registrator.codecService);
Jian Li2d3a1d12017-04-05 00:56:54 +090081 valueCodec = context.codec(MappingValue.class);
82 assertThat(valueCodec, notNullValue());
83 }
84
85 /**
86 * Deactivates the codec registrator.
87 */
88 @After
89 public void tearDown() {
90 registrator.deactivate();
91 }
92
93 /**
94 * Tests encoding of a mapping value object.
95 */
96 @Test
Jian Lib5d82212017-04-25 01:45:18 +090097 public void testMappingValueEncode() {
Jian Li2d3a1d12017-04-05 00:56:54 +090098 MappingInstruction unicastWeight = MappingInstructions.unicastWeight(UNICAST_WEIGHT);
99 MappingInstruction unicastPriority = MappingInstructions.unicastPriority(UNICAST_PRIORITY);
100 MappingInstruction multicastWeight = MappingInstructions.multicastWeight(MULTICAST_WEIGHT);
101 MappingInstruction multicastPriority = MappingInstructions.multicastPriority(MULTICAST_PRIORITY);
102
103 MappingAddress address = MappingAddresses.ipv4MappingAddress(IPV4_PREFIX);
104
105 MappingTreatment treatment = DefaultMappingTreatment.builder()
106 .add(unicastWeight)
107 .add(unicastPriority)
108 .add(multicastWeight)
109 .add(multicastPriority)
110 .withAddress(address)
111 .build();
112
113 MappingAction action = MappingActions.noAction();
114
115 MappingValue value = DefaultMappingValue.builder()
116 .add(treatment)
117 .withAction(action)
118 .build();
119
120 ObjectNode valueJson = valueCodec.encode(value, context);
121 assertThat(valueJson, MappingValueJsonMatcher.matchesMappingValue(value));
122 }
123
124 /**
125 * Tests decoding of a mapping value JSON object.
126 */
127 @Test
128 public void testMappingValueDecode() throws IOException {
129 MappingValue value = getValue("MappingValue.json");
130 assertThat(value.treatments().get(0).address().toString(),
131 is("IPV4:" + IPV4_STRING + "/" + PORT_STRING));
132 }
133
134
135 /**
136 * Hamcrest matcher for mapping value.
137 */
138 public static final class MappingValueJsonMatcher
139 extends TypeSafeDiagnosingMatcher<JsonNode> {
140
141 private final MappingValue mappingValue;
142
143 /**
144 * A default constructor.
145 *
146 * @param mappingValue mapping value
147 */
148 private MappingValueJsonMatcher(MappingValue mappingValue) {
149 this.mappingValue = mappingValue;
150 }
151
152 @Override
153 protected boolean matchesSafely(JsonNode jsonNode, Description description) {
154
155 // check mapping treatments
156 final JsonNode jsonTreatments = jsonNode.get(TREATMENTS);
157 if (mappingValue.treatments().size() != jsonTreatments.size()) {
158 description.appendText("mapping treatments array size of " +
159 Integer.toString(mappingValue.treatments().size()));
160 return false;
161 }
162
163 for (final MappingTreatment treatment : mappingValue.treatments()) {
164 boolean treatmentFound = false;
165 for (int treatmentIdx = 0; treatmentIdx < jsonTreatments.size();
166 treatmentIdx++) {
167 final String jsonAddress =
168 jsonTreatments.get(treatmentIdx).get(ADDRESS)
169 .get(MappingAddressCodec.IPV4).textValue();
170 final String address = treatment.address().toString();
171 if (address.contains(jsonAddress)) {
172 treatmentFound = true;
173 }
174 }
175
176 if (!treatmentFound) {
177 description.appendText("mapping treatment " + treatment.toString());
178 return false;
179 }
180 }
181
182 // check mapping action
183 final JsonNode jsonActionNode = jsonNode.get(MappingValueCodec.ACTION);
184
185 assertThat(jsonActionNode, MappingActionJsonMatcher.matchesAction(mappingValue.action()));
186
187 return true;
188 }
189
190 @Override
191 public void describeTo(Description description) {
192 description.appendText(mappingValue.toString());
193 }
194
195 /**
196 * Factory to allocate a mapping value.
197 *
198 * @param mappingValue mapping value object we are looking for
199 * @return matcher
200 */
201 static MappingValueJsonMatcher matchesMappingValue(MappingValue mappingValue) {
202 return new MappingValueJsonMatcher(mappingValue);
203 }
204 }
205
206 /**
Jian Li2d3a1d12017-04-05 00:56:54 +0900207 * Reads in a mapping value from the given resource and decodes it.
208 *
209 * @param resourceName resource to use to read the JSON for the rule
210 * @return decoded mappingKey
211 * @throws IOException if processing the resource fails
212 */
213 private MappingValue getValue(String resourceName) throws IOException {
214 InputStream jsonStream = MappingValueCodecTest.class.getResourceAsStream(resourceName);
215 JsonNode json = context.mapper().readTree(jsonStream);
216 assertThat(json, notNullValue());
217 MappingValue value = valueCodec.decode((ObjectNode) json, context);
218 assertThat(value, notNullValue());
219 return value;
220 }
221}