]> git.basschouten.com Git - openhab-addons.git/blob
08f86c673c65808d6705f7bb7c158748c4f4f29b
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.snmp.internal;
14
15 import static org.junit.Assert.*;
16 import static org.mockito.ArgumentMatchers.*;
17 import static org.mockito.Mockito.*;
18 import static org.openhab.binding.snmp.internal.SnmpBindingConstants.THING_TYPE_TARGET;
19
20 import java.io.IOException;
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.Map;
24 import java.util.Vector;
25
26 import org.mockito.ArgumentCaptor;
27 import org.mockito.Mock;
28 import org.mockito.MockitoAnnotations;
29 import org.openhab.core.config.core.Configuration;
30 import org.openhab.core.library.types.StringType;
31 import org.openhab.core.test.java.JavaTest;
32 import org.openhab.core.thing.Channel;
33 import org.openhab.core.thing.ChannelUID;
34 import org.openhab.core.thing.Thing;
35 import org.openhab.core.thing.ThingStatus;
36 import org.openhab.core.thing.ThingUID;
37 import org.openhab.core.thing.binding.ThingHandlerCallback;
38 import org.openhab.core.thing.binding.builder.ChannelBuilder;
39 import org.openhab.core.thing.binding.builder.ThingBuilder;
40 import org.openhab.core.thing.type.ChannelTypeUID;
41 import org.openhab.core.types.Command;
42 import org.openhab.core.types.State;
43 import org.snmp4j.PDU;
44 import org.snmp4j.event.ResponseEvent;
45 import org.snmp4j.smi.OID;
46 import org.snmp4j.smi.OctetString;
47 import org.snmp4j.smi.Variable;
48 import org.snmp4j.smi.VariableBinding;
49
50 /**
51  * Tests cases for {@link SnmpTargetHandler}.
52  *
53  * @author Jan N. Klug - Initial contribution
54  */
55 public abstract class AbstractSnmpTargetHandlerTest extends JavaTest {
56     protected static final ThingUID THING_UID = new ThingUID(THING_TYPE_TARGET, "testthing");
57     protected static final ChannelUID CHANNEL_UID = new ChannelUID(THING_UID, "testchannel");
58     protected static final String TEST_OID = "1.2.3.4";
59     protected static final String TEST_ADDRESS = "192.168.0.1";
60     protected static final String TEST_STRING = "foo.";
61
62     protected @Mock SnmpServiceImpl snmpService;
63     protected @Mock ThingHandlerCallback thingHandlerCallback;
64
65     protected Thing thing;
66     protected SnmpTargetHandler thingHandler;
67
68     protected VariableBinding handleCommandSwitchChannel(SnmpDatatype datatype, Command command, String onValue,
69             String offValue, boolean refresh) throws IOException {
70         setup(SnmpBindingConstants.CHANNEL_TYPE_UID_SWITCH, SnmpChannelMode.WRITE, datatype, onValue, offValue);
71         thingHandler.handleCommand(CHANNEL_UID, command);
72
73         if (refresh) {
74             ArgumentCaptor<PDU> pduCaptor = ArgumentCaptor.forClass(PDU.class);
75             verify(snmpService, times(1)).send(pduCaptor.capture(), any(), eq(null), eq(thingHandler));
76             return pduCaptor.getValue().getVariableBindings().stream().findFirst().orElse(null);
77         } else {
78             verify(snmpService, never()).send(any(), any(), eq(null), eq(thingHandler));
79             return null;
80         }
81     }
82
83     protected VariableBinding handleCommandNumberStringChannel(ChannelTypeUID channelTypeUID, SnmpDatatype datatype,
84             Command command, boolean refresh) throws IOException {
85         setup(channelTypeUID, SnmpChannelMode.WRITE, datatype);
86         thingHandler.handleCommand(CHANNEL_UID, command);
87
88         if (refresh) {
89             ArgumentCaptor<PDU> pduCaptor = ArgumentCaptor.forClass(PDU.class);
90             verify(snmpService, times(1)).send(pduCaptor.capture(), any(), eq(null), eq(thingHandler));
91             return pduCaptor.getValue().getVariableBindings().stream().findFirst().orElse(null);
92         } else {
93             verify(snmpService, never()).send(any(), any(), eq(null), eq(thingHandler));
94             return null;
95         }
96     }
97
98     protected void onResponseNumberStringChannel(SnmpChannelMode channelMode, boolean refresh) {
99         setup(SnmpBindingConstants.CHANNEL_TYPE_UID_STRING, channelMode);
100
101         PDU responsePDU = new PDU(PDU.RESPONSE,
102                 Collections.singletonList(new VariableBinding(new OID(TEST_OID), new OctetString(TEST_STRING))));
103         ResponseEvent event = new ResponseEvent("test", null, null, responsePDU, null);
104
105         thingHandler.onResponse(event);
106
107         if (refresh) {
108             verify(thingHandlerCallback, atLeast(1)).stateUpdated(eq(CHANNEL_UID), eq(new StringType(TEST_STRING)));
109         } else {
110             verify(thingHandlerCallback, never()).stateUpdated(any(), any());
111         }
112     }
113
114     protected State onResponseSwitchChannel(SnmpChannelMode channelMode, SnmpDatatype datatype, String onValue,
115             String offValue, Variable value, boolean refresh) {
116         setup(SnmpBindingConstants.CHANNEL_TYPE_UID_SWITCH, channelMode, datatype, onValue, offValue);
117
118         PDU responsePDU = new PDU(PDU.RESPONSE,
119                 Collections.singletonList(new VariableBinding(new OID(TEST_OID), value)));
120         ResponseEvent event = new ResponseEvent("test", null, null, responsePDU, null);
121
122         thingHandler.onResponse(event);
123
124         if (refresh) {
125             ArgumentCaptor<State> stateCaptor = ArgumentCaptor.forClass(State.class);
126             verify(thingHandlerCallback, atLeast(1)).stateUpdated(eq(CHANNEL_UID), stateCaptor.capture());
127             return stateCaptor.getValue();
128         } else {
129             verify(thingHandlerCallback, never()).stateUpdated(any(), any());
130             return null;
131         }
132     }
133
134     protected void refresh(SnmpChannelMode channelMode, boolean refresh) throws IOException {
135         setup(SnmpBindingConstants.CHANNEL_TYPE_UID_STRING, channelMode);
136
137         waitForAssert(() -> assertEquals(ThingStatus.ONLINE, thingHandler.getThing().getStatusInfo().getStatus()));
138         verify(snmpService).addCommandResponder(any());
139
140         if (refresh) {
141             ArgumentCaptor<PDU> pduCaptor = ArgumentCaptor.forClass(PDU.class);
142             verify(snmpService, atLeast(1)).send(pduCaptor.capture(), any(), eq(null), eq(thingHandler));
143             Vector<? extends VariableBinding> variables = pduCaptor.getValue().getVariableBindings();
144             assertTrue(variables.stream().filter(v -> v.getOid().toDottedString().equals(TEST_OID)).findFirst()
145                     .isPresent());
146         } else {
147             verify(snmpService, never()).send(any(), any(), eq(null), eq(thingHandler));
148         }
149     }
150
151     protected void setup(ChannelTypeUID channelTypeUID, SnmpChannelMode channelMode) {
152         setup(channelTypeUID, channelMode, null);
153     }
154
155     protected void setup(ChannelTypeUID channelTypeUID, SnmpChannelMode channelMode, SnmpDatatype datatype) {
156         setup(channelTypeUID, channelMode, datatype, null, null);
157     }
158
159     protected void setup(ChannelTypeUID channelTypeUID, SnmpChannelMode channelMode, SnmpDatatype datatype,
160             String onValue, String offValue) {
161         setup(channelTypeUID, channelMode, datatype, onValue, offValue, null);
162     }
163
164     protected void setup(ChannelTypeUID channelTypeUID, SnmpChannelMode channelMode, SnmpDatatype datatype,
165             String onValue, String offValue, String exceptionValue) {
166         Map<String, Object> channelConfig = new HashMap<>();
167         Map<String, Object> thingConfig = new HashMap<>();
168         MockitoAnnotations.initMocks(this);
169
170         thingConfig.put("hostname", "localhost");
171
172         ThingBuilder thingBuilder = ThingBuilder.create(THING_TYPE_TARGET, THING_UID).withLabel("Test thing")
173                 .withConfiguration(new Configuration(thingConfig));
174
175         if (channelTypeUID != null && channelMode != null) {
176             String itemType = SnmpBindingConstants.CHANNEL_TYPE_UID_NUMBER.equals(channelTypeUID) ? "Number" : "String";
177             channelConfig.put("oid", TEST_OID);
178             channelConfig.put("mode", channelMode.name());
179             if (datatype != null) {
180                 channelConfig.put("datatype", datatype.name());
181             }
182             if (onValue != null) {
183                 channelConfig.put("onvalue", onValue);
184             }
185             if (offValue != null) {
186                 channelConfig.put("offvalue", offValue);
187             }
188             if (exceptionValue != null) {
189                 channelConfig.put("exceptionValue", exceptionValue);
190             }
191             Channel channel = ChannelBuilder.create(CHANNEL_UID, itemType).withType(channelTypeUID)
192                     .withConfiguration(new Configuration(channelConfig)).build();
193             thingBuilder.withChannel(channel);
194         }
195
196         thing = thingBuilder.build();
197         thingHandler = new SnmpTargetHandler(thing, snmpService);
198
199         thingHandler.getThing().setHandler(thingHandler);
200         thingHandler.setCallback(thingHandlerCallback);
201
202         doAnswer(answer -> {
203             ((Thing) answer.getArgument(0)).setStatusInfo(answer.getArgument(1));
204             return null;
205         }).when(thingHandlerCallback).statusUpdated(any(), any());
206
207         thingHandler.initialize();
208
209         waitForAssert(() -> assertEquals(ThingStatus.ONLINE, thingHandler.getThing().getStatusInfo().getStatus()));
210     }
211 }