]> git.basschouten.com Git - openhab-addons.git/blob
0c8394732d3aa43ed1e292401942c7140fa8d992
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.systeminfo.test;
14
15 import static java.lang.Thread.sleep;
16 import static org.hamcrest.CoreMatchers.*;
17 import static org.hamcrest.MatcherAssert.assertThat;
18 import static org.junit.jupiter.api.Assertions.assertFalse;
19 import static org.mockito.Mockito.*;
20
21 import java.math.BigDecimal;
22 import java.net.UnknownHostException;
23 import java.util.Hashtable;
24 import java.util.List;
25 import java.util.Map;
26
27 import javax.measure.quantity.ElectricPotential;
28 import javax.measure.quantity.Frequency;
29 import javax.measure.quantity.Temperature;
30 import javax.measure.quantity.Time;
31
32 import org.eclipse.jdt.annotation.NonNullByDefault;
33 import org.eclipse.jdt.annotation.Nullable;
34 import org.junit.jupiter.api.AfterEach;
35 import org.junit.jupiter.api.BeforeEach;
36 import org.junit.jupiter.api.Test;
37 import org.junit.jupiter.api.extension.ExtendWith;
38 import org.mockito.Mock;
39 import org.mockito.junit.jupiter.MockitoExtension;
40 import org.mockito.junit.jupiter.MockitoSettings;
41 import org.mockito.quality.Strictness;
42 import org.openhab.binding.systeminfo.internal.SysteminfoBindingConstants;
43 import org.openhab.binding.systeminfo.internal.SysteminfoHandlerFactory;
44 import org.openhab.binding.systeminfo.internal.discovery.SysteminfoDiscoveryService;
45 import org.openhab.binding.systeminfo.internal.handler.SysteminfoHandler;
46 import org.openhab.binding.systeminfo.internal.model.DeviceNotFoundException;
47 import org.openhab.binding.systeminfo.internal.model.OSHISysteminfo;
48 import org.openhab.binding.systeminfo.internal.model.SysteminfoInterface;
49 import org.openhab.core.config.core.Configuration;
50 import org.openhab.core.config.discovery.DiscoveryResult;
51 import org.openhab.core.config.discovery.DiscoveryService;
52 import org.openhab.core.config.discovery.inbox.Inbox;
53 import org.openhab.core.config.discovery.inbox.InboxPredicates;
54 import org.openhab.core.i18n.UnitProvider;
55 import org.openhab.core.items.GenericItem;
56 import org.openhab.core.items.ItemNotFoundException;
57 import org.openhab.core.items.ItemRegistry;
58 import org.openhab.core.library.dimension.DataAmount;
59 import org.openhab.core.library.items.NumberItem;
60 import org.openhab.core.library.items.StringItem;
61 import org.openhab.core.library.types.DecimalType;
62 import org.openhab.core.library.types.PercentType;
63 import org.openhab.core.library.types.QuantityType;
64 import org.openhab.core.library.types.StringType;
65 import org.openhab.core.library.unit.SIUnits;
66 import org.openhab.core.library.unit.Units;
67 import org.openhab.core.test.java.JavaOSGiTest;
68 import org.openhab.core.test.storage.VolatileStorageService;
69 import org.openhab.core.thing.Channel;
70 import org.openhab.core.thing.ChannelUID;
71 import org.openhab.core.thing.ManagedThingProvider;
72 import org.openhab.core.thing.Thing;
73 import org.openhab.core.thing.ThingProvider;
74 import org.openhab.core.thing.ThingRegistry;
75 import org.openhab.core.thing.ThingStatus;
76 import org.openhab.core.thing.ThingStatusDetail;
77 import org.openhab.core.thing.ThingTypeUID;
78 import org.openhab.core.thing.ThingUID;
79 import org.openhab.core.thing.binding.ThingHandler;
80 import org.openhab.core.thing.binding.ThingHandlerFactory;
81 import org.openhab.core.thing.binding.builder.ChannelBuilder;
82 import org.openhab.core.thing.binding.builder.ThingBuilder;
83 import org.openhab.core.thing.link.ItemChannelLink;
84 import org.openhab.core.thing.link.ManagedItemChannelLinkProvider;
85 import org.openhab.core.thing.type.ChannelKind;
86 import org.openhab.core.thing.type.ChannelTypeUID;
87 import org.openhab.core.types.State;
88 import org.openhab.core.types.UnDefType;
89
90 /**
91  * OSGi tests for the {@link SysteminfoHandler}
92  *
93  * @author Svilen Valkanov - Initial contribution
94  * @author Lyubomir Papazov - Created a mock systeminfo object. This way, access to the user's OS will not be required,
95  *         but mock data will be used instead, avoiding potential errors from the OS queries.
96  * @author Wouter Born - Migrate Groovy to Java tests
97  * @author Mark Herwege - Processor frequency channels
98  */
99 @NonNullByDefault
100 @ExtendWith(MockitoExtension.class)
101 @MockitoSettings(strictness = Strictness.LENIENT)
102 public class SysteminfoOSGiTest extends JavaOSGiTest {
103
104     private static final String DEFAULT_TEST_THING_NAME = "work";
105     private static final String DEFAULT_TEST_ITEM_NAME = "test";
106     private static final String DEFAULT_CHANNEL_TEST_PRIORITY = "High";
107     private static final int DEFAULT_CHANNEL_PID = -1;
108     private static final String DEFAULT_TEST_CHANNEL_ID = SysteminfoBindingConstants.CHANNEL_CPU_LOAD;
109     private static final int DEFAULT_DEVICE_INDEX = 0;
110
111     /**
112      * Refresh time in seconds for tasks with priority High.
113      * Default value for the parameter interval_high in the thing configuration
114      */
115     private static final int DEFAULT_TEST_INTERVAL_HIGH = 1;
116
117     /**
118      * Refresh time in seconds for tasks with priority Medium.
119      */
120     private static final int DEFAULT_TEST_INTERVAL_MEDIUM = 3;
121
122     private @Nullable Thing systeminfoThing;
123     private @Nullable GenericItem testItem;
124
125     private @Mock @NonNullByDefault({}) OSHISysteminfo mockedSystemInfo;
126     private @NonNullByDefault({}) SysteminfoHandlerFactory systeminfoHandlerFactory;
127     private @NonNullByDefault({}) ThingRegistry thingRegistry;
128     private @NonNullByDefault({}) ItemRegistry itemRegistry;
129     private @NonNullByDefault({}) ManagedThingProvider managedThingProvider;
130     private @NonNullByDefault({}) ManagedItemChannelLinkProvider itemChannelLinkProvider;
131     private @NonNullByDefault({}) UnitProvider unitProvider;
132     private @NonNullByDefault({}) VolatileStorageService volatileStorageService;
133
134     @BeforeEach
135     public void setUp() {
136         volatileStorageService = new VolatileStorageService();
137         registerService(volatileStorageService);
138
139         // Preparing the mock with OS properties, that are used in the initialize method of SysteminfoHandler
140         // Make this lenient because the assertInvalidThingConfigurationValuesAreHandled test does not require them
141         lenient().when(mockedSystemInfo.getCpuLogicalCores()).thenReturn(new DecimalType(1));
142         lenient().when(mockedSystemInfo.getCpuPhysicalCores()).thenReturn(new DecimalType(1));
143         lenient().when(mockedSystemInfo.getOsFamily()).thenReturn(new StringType("Mock OS"));
144         lenient().when(mockedSystemInfo.getOsManufacturer()).thenReturn(new StringType("Mock OS Manufacturer"));
145         lenient().when(mockedSystemInfo.getOsVersion()).thenReturn(new StringType("Mock Os Version"));
146         // Following mock method returns will make sure the thing does not get recreated with extra channels
147         lenient().when(mockedSystemInfo.getNetworkIFCount()).thenReturn(1);
148         lenient().when(mockedSystemInfo.getDisplayCount()).thenReturn(1);
149         lenient().when(mockedSystemInfo.getFileOSStoreCount()).thenReturn(1);
150         lenient().when(mockedSystemInfo.getPowerSourceCount()).thenReturn(1);
151         lenient().when(mockedSystemInfo.getDriveCount()).thenReturn(1);
152         lenient().when(mockedSystemInfo.getFanCount()).thenReturn(1);
153
154         registerService(mockedSystemInfo);
155
156         waitForAssert(() -> {
157             systeminfoHandlerFactory = getService(ThingHandlerFactory.class, SysteminfoHandlerFactory.class);
158             assertThat(systeminfoHandlerFactory, is(notNullValue()));
159         });
160
161         if (systeminfoHandlerFactory != null) {
162             // Unbind oshiSystemInfo service and bind the mock service to make the systeminfo binding tests independent
163             // of the external OSHI library
164             SysteminfoInterface oshiSystemInfo = getService(SysteminfoInterface.class);
165             if (oshiSystemInfo != null) {
166                 systeminfoHandlerFactory.unbindSystemInfo(oshiSystemInfo);
167             }
168             systeminfoHandlerFactory.bindSystemInfo(mockedSystemInfo);
169         }
170
171         waitForAssert(() -> {
172             thingRegistry = getService(ThingRegistry.class);
173             assertThat(thingRegistry, is(notNullValue()));
174         });
175
176         waitForAssert(() -> {
177             itemRegistry = getService(ItemRegistry.class);
178             assertThat(itemRegistry, is(notNullValue()));
179         });
180
181         waitForAssert(() -> {
182             managedThingProvider = getService(ThingProvider.class, ManagedThingProvider.class);
183             assertThat(managedThingProvider, is(notNullValue()));
184         });
185
186         waitForAssert(() -> {
187             itemChannelLinkProvider = getService(ManagedItemChannelLinkProvider.class);
188             assertThat(itemChannelLinkProvider, is(notNullValue()));
189         });
190
191         waitForAssert(() -> {
192             unitProvider = getService(UnitProvider.class);
193             assertThat(unitProvider, is(notNullValue()));
194         });
195     }
196
197     @AfterEach
198     public void tearDown() {
199         Thing thing = systeminfoThing;
200         if (thing != null) {
201             // Remove the systeminfo thing. The handler will also be disposed automatically
202             Thing removedThing = thingRegistry.forceRemove(thing.getUID());
203             assertThat("The systeminfo thing cannot be deleted", removedThing, is(notNullValue()));
204             waitForAssert(() -> {
205                 ThingHandler systemInfoHandler = thing.getHandler();
206                 assertThat(systemInfoHandler, is(nullValue()));
207             });
208             managedThingProvider.remove(thing.getUID());
209         }
210
211         if (testItem != null) {
212             itemRegistry.remove(DEFAULT_TEST_ITEM_NAME);
213         }
214
215         unregisterService(mockedSystemInfo);
216         unregisterService(volatileStorageService);
217     }
218
219     private void initializeThingWithChannelAndPID(String channelID, String acceptedItemType, int pid) {
220         Configuration thingConfig = new Configuration();
221         thingConfig.put(SysteminfoBindingConstants.HIGH_PRIORITY_REFRESH_TIME,
222                 new BigDecimal(DEFAULT_TEST_INTERVAL_HIGH));
223         thingConfig.put(SysteminfoBindingConstants.MEDIUM_PRIORITY_REFRESH_TIME,
224                 new BigDecimal(DEFAULT_TEST_INTERVAL_MEDIUM));
225         String priority = DEFAULT_CHANNEL_TEST_PRIORITY;
226
227         initializeThing(thingConfig, channelID, acceptedItemType, priority, pid);
228     }
229
230     private void initializeThingWithChannelAndPriority(String channelID, String acceptedItemType, String priority) {
231         Configuration thingConfig = new Configuration();
232         thingConfig.put(SysteminfoBindingConstants.HIGH_PRIORITY_REFRESH_TIME,
233                 new BigDecimal(DEFAULT_TEST_INTERVAL_HIGH));
234         thingConfig.put(SysteminfoBindingConstants.MEDIUM_PRIORITY_REFRESH_TIME,
235                 new BigDecimal(DEFAULT_TEST_INTERVAL_MEDIUM));
236         int pid = DEFAULT_CHANNEL_PID;
237
238         initializeThing(thingConfig, channelID, acceptedItemType, priority, pid);
239     }
240
241     private void initializeThingWithConfiguration(Configuration config) {
242         String priority = DEFAULT_CHANNEL_TEST_PRIORITY;
243         String channelID = DEFAULT_TEST_CHANNEL_ID;
244         String acceptedItemType = "String";
245         int pid = DEFAULT_CHANNEL_PID;
246
247         initializeThing(config, channelID, acceptedItemType, priority, pid);
248     }
249
250     private void initializeThingWithChannel(String channelID, String acceptedItemType) {
251         Configuration thingConfig = new Configuration();
252         thingConfig.put(SysteminfoBindingConstants.HIGH_PRIORITY_REFRESH_TIME,
253                 new BigDecimal(DEFAULT_TEST_INTERVAL_HIGH));
254         thingConfig.put(SysteminfoBindingConstants.MEDIUM_PRIORITY_REFRESH_TIME,
255                 new BigDecimal(DEFAULT_TEST_INTERVAL_MEDIUM));
256
257         String priority = DEFAULT_CHANNEL_TEST_PRIORITY;
258         int pid = DEFAULT_CHANNEL_PID;
259         initializeThing(thingConfig, channelID, acceptedItemType, priority, pid);
260     }
261
262     private void initializeThing(Configuration thingConfiguration, String channelID, String acceptedItemType,
263             String priority, int pid) {
264         ThingTypeUID thingTypeUID = SysteminfoBindingConstants.THING_TYPE_COMPUTER;
265         ThingUID thingUID = new ThingUID(thingTypeUID, DEFAULT_TEST_THING_NAME);
266
267         ChannelUID channelUID = new ChannelUID(thingUID, channelID);
268         String channelTypeId = channelUID.getIdWithoutGroup();
269         if ("load1".equals(channelTypeId) || "load5".equals(channelTypeId) || "load15".equals(channelTypeId)) {
270             channelTypeId = "loadAverage";
271         }
272         ChannelTypeUID channelTypeUID = new ChannelTypeUID(SysteminfoBindingConstants.BINDING_ID, channelTypeId);
273         Configuration channelConfig = new Configuration();
274         channelConfig.put("priority", priority);
275         channelConfig.put("pid", new BigDecimal(pid));
276         Channel channel = ChannelBuilder.create(channelUID, acceptedItemType).withType(channelTypeUID)
277                 .withKind(ChannelKind.STATE).withConfiguration(channelConfig).build();
278
279         ThingBuilder thingBuilder = ThingBuilder.create(thingTypeUID, thingUID).withConfiguration(thingConfiguration)
280                 .withChannel(channel);
281         // Make sure the thingTypeVersion matches the highest version in the update instructions of the binding to avoid
282         // new channels being added and the thing not initializing
283         thingBuilder = thingBuilder.withProperties(Map.of("thingTypeVersion", "1"));
284         Thing thing = thingBuilder.build();
285         systeminfoThing = thing;
286
287         managedThingProvider.add(thing);
288
289         waitForAssert(() -> {
290             SysteminfoHandler handler = (SysteminfoHandler) thing.getHandler();
291             assertThat(handler, is(notNullValue()));
292         });
293
294         waitForAssert(() -> {
295             assertThat("Thing is not initialized, before an Item is created", thing.getStatus(),
296                     anyOf(equalTo(ThingStatus.OFFLINE), equalTo(ThingStatus.ONLINE)));
297         });
298
299         intializeItem(channelUID, DEFAULT_TEST_ITEM_NAME, acceptedItemType);
300     }
301
302     private void assertItemState(String acceptedItemType, String itemName, String priority, State expectedState) {
303         Thing thing = systeminfoThing;
304         if (thing == null) {
305             throw new AssertionError("Thing is null");
306         }
307         waitForAssert(() -> {
308             ThingStatusDetail thingStatusDetail = thing.getStatusInfo().getStatusDetail();
309             String description = thing.getStatusInfo().getDescription();
310             assertThat("Thing status detail is " + thingStatusDetail + " with description " + description,
311                     thing.getStatus(), is(equalTo(ThingStatus.ONLINE)));
312         });
313         // The binding starts all refresh tasks in SysteminfoHandler.scheduleUpdates() after this delay !
314         try {
315             sleep(SysteminfoHandler.WAIT_TIME_CHANNEL_ITEM_LINK_INIT * 1000);
316         } catch (InterruptedException e) {
317             throw new AssertionError("Interrupted while sleeping");
318         }
319
320         GenericItem item;
321         try {
322             item = (GenericItem) itemRegistry.getItem(itemName);
323         } catch (ItemNotFoundException e) {
324             throw new AssertionError("Item not found in registry");
325         }
326
327         int waitTime;
328         if ("High".equals(priority)) {
329             waitTime = DEFAULT_TEST_INTERVAL_HIGH * 1000;
330         } else if ("Medium".equals(priority)) {
331             waitTime = DEFAULT_TEST_INTERVAL_MEDIUM * 1000;
332         } else {
333             waitTime = 100;
334         }
335
336         waitForAssert(() -> {
337             State itemState = item.getState();
338             assertThat(itemState, is(equalTo(expectedState)));
339         }, waitTime, DFL_SLEEP_TIME);
340     }
341
342     private void intializeItem(ChannelUID channelUID, String itemName, String acceptedItemType) {
343         GenericItem item = null;
344         if (acceptedItemType.startsWith("Number")) {
345             item = new NumberItem(acceptedItemType, itemName, unitProvider);
346         } else if ("String".equals(acceptedItemType)) {
347             item = new StringItem(itemName);
348         }
349         if (item == null) {
350             throw new AssertionError("Item is null");
351         }
352         itemRegistry.add(item);
353         testItem = item;
354
355         itemChannelLinkProvider.add(new ItemChannelLink(itemName, channelUID));
356     }
357
358     @Test
359     public void assertInvalidThingConfigurationValuesAreHandled() {
360         Configuration configuration = new Configuration();
361
362         // invalid value - must be positive
363         int refreshIntervalHigh = -5;
364         configuration.put(SysteminfoBindingConstants.HIGH_PRIORITY_REFRESH_TIME, new BigDecimal(refreshIntervalHigh));
365
366         int refreshIntervalMedium = 3;
367         configuration.put(SysteminfoBindingConstants.MEDIUM_PRIORITY_REFRESH_TIME,
368                 new BigDecimal(refreshIntervalMedium));
369         initializeThingWithConfiguration(configuration);
370
371         testInvalidConfiguration();
372     }
373
374     private void testInvalidConfiguration() {
375         waitForAssert(() -> {
376             Thing thing = systeminfoThing;
377             if (thing != null) {
378                 assertThat("Invalid configuration is used !", thing.getStatus(), is(equalTo(ThingStatus.OFFLINE)));
379                 assertThat(thing.getStatusInfo().getStatusDetail(),
380                         is(equalTo(ThingStatusDetail.HANDLER_INITIALIZING_ERROR)));
381                 assertThat(thing.getStatusInfo().getDescription(), is(equalTo("@text/offline.cannot-initialize")));
382             }
383         });
384     }
385
386     @Test
387     public void assertMediumPriorityChannelIsUpdated() {
388         String channnelID = DEFAULT_TEST_CHANNEL_ID;
389         String acceptedItemType = "Number";
390         String priority = "Medium";
391
392         initializeThingWithChannelAndPriority(channnelID, acceptedItemType, priority);
393         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, priority, UnDefType.UNDEF);
394     }
395
396     @Test
397     public void assertStateOfSecondDeviceIsUpdated() {
398         // This test assumes that at least 2 network interfaces are present on the test platform
399         int deviceIndex = 1;
400         String channnelID = "network" + deviceIndex + "#mac";
401         String acceptedItemType = "String";
402
403         initializeThingWithChannel(channnelID, acceptedItemType);
404         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, UnDefType.UNDEF);
405     }
406
407     @Test
408     public void assertChannelCpuMaxFreq() {
409         String channnelID = SysteminfoBindingConstants.CHANNEL_CPU_MAXFREQ;
410         String acceptedItemType = "Number:Frequency";
411
412         QuantityType<Frequency> mockedCpuMaxFreqValue = new QuantityType<>(2500, Units.HERTZ);
413         when(mockedSystemInfo.getCpuMaxFreq()).thenReturn(mockedCpuMaxFreqValue);
414
415         initializeThingWithChannel(channnelID, acceptedItemType);
416         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedCpuMaxFreqValue);
417     }
418
419     @Test
420     public void assertChannelCpuFreq() {
421         String channnelID = SysteminfoBindingConstants.CHANNEL_CPU_FREQ;
422         String acceptedItemType = "Number:Frequency";
423
424         QuantityType<Frequency> mockedCpuFreqValue = new QuantityType<>(2500, Units.HERTZ);
425         when(mockedSystemInfo.getCpuFreq(0)).thenReturn(mockedCpuFreqValue);
426
427         initializeThingWithChannel(channnelID, acceptedItemType);
428         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedCpuFreqValue);
429     }
430
431     @Test
432     public void assertChannelCpuLoadIsUpdated() {
433         String channnelID = SysteminfoBindingConstants.CHANNEL_CPU_LOAD;
434         String acceptedItemType = "Number";
435
436         PercentType mockedCpuLoadValue = new PercentType(9);
437         when(mockedSystemInfo.getSystemCpuLoad()).thenReturn(mockedCpuLoadValue);
438
439         initializeThingWithChannel(channnelID, acceptedItemType);
440         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedCpuLoadValue);
441     }
442
443     @Test
444     public void assertChannelCpuLoad1IsUpdated() {
445         String channnelID = SysteminfoBindingConstants.CHANNEL_CPU_LOAD_1;
446         String acceptedItemType = "Number";
447
448         DecimalType mockedCpuLoad1Value = new DecimalType(1.1);
449         when(mockedSystemInfo.getCpuLoad1()).thenReturn(mockedCpuLoad1Value);
450
451         initializeThingWithChannel(channnelID, acceptedItemType);
452         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedCpuLoad1Value);
453     }
454
455     @Test
456     public void assertChannelCpuLoad5IsUpdated() {
457         String channnelID = SysteminfoBindingConstants.CHANNEL_CPU_LOAD_5;
458         String acceptedItemType = "Number";
459
460         DecimalType mockedCpuLoad5Value = new DecimalType(5.5);
461         when(mockedSystemInfo.getCpuLoad5()).thenReturn(mockedCpuLoad5Value);
462
463         initializeThingWithChannel(channnelID, acceptedItemType);
464         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedCpuLoad5Value);
465     }
466
467     @Test
468     public void assertChannelCpuLoad15IsUpdated() {
469         String channnelID = SysteminfoBindingConstants.CHANNEL_CPU_LOAD_15;
470         String acceptedItemType = "Number";
471
472         DecimalType mockedCpuLoad15Value = new DecimalType(15.15);
473         when(mockedSystemInfo.getCpuLoad15()).thenReturn(mockedCpuLoad15Value);
474
475         initializeThingWithChannel(channnelID, acceptedItemType);
476         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedCpuLoad15Value);
477     }
478
479     @Test
480     public void assertChannelCpuThreadsIsUpdated() {
481         String channnelID = SysteminfoBindingConstants.CHANNEL_CPU_THREADS;
482         String acceptedItemType = "Number";
483
484         DecimalType mockedCpuThreadsValue = new DecimalType(16);
485         when(mockedSystemInfo.getCpuThreads()).thenReturn(mockedCpuThreadsValue);
486
487         initializeThingWithChannel(channnelID, acceptedItemType);
488         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedCpuThreadsValue);
489     }
490
491     @Test
492     public void assertChannelCpuUptimeIsUpdated() {
493         String channnelID = SysteminfoBindingConstants.CHANNEL_CPU_UPTIME;
494         String acceptedItemType = "Number:Time";
495
496         QuantityType<Time> mockedCpuUptimeValue = new QuantityType<>(100, Units.MINUTE);
497         when(mockedSystemInfo.getCpuUptime()).thenReturn(mockedCpuUptimeValue);
498
499         initializeThingWithChannel(channnelID, acceptedItemType);
500         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedCpuUptimeValue);
501     }
502
503     @Test
504     public void assertChannelCpuDescriptionIsUpdated() {
505         String channnelID = SysteminfoBindingConstants.CHANNEL_CPU_DESCRIPTION;
506         String acceptedItemType = "String";
507
508         StringType mockedCpuDescriptionValue = new StringType("Mocked Cpu Descr");
509         when(mockedSystemInfo.getCpuDescription()).thenReturn(mockedCpuDescriptionValue);
510
511         initializeThingWithChannel(channnelID, acceptedItemType);
512         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
513                 mockedCpuDescriptionValue);
514     }
515
516     @Test
517     public void assertChannelCpuNameIsUpdated() {
518         String channnelID = SysteminfoBindingConstants.CHANNEL_CPU_NAME;
519         String acceptedItemType = "String";
520
521         StringType mockedCpuNameValue = new StringType("Mocked Cpu Name");
522         when(mockedSystemInfo.getCpuName()).thenReturn(mockedCpuNameValue);
523
524         initializeThingWithChannel(channnelID, acceptedItemType);
525         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedCpuNameValue);
526     }
527
528     @Test
529     public void assertChannelMemoryAvailableIsUpdated() {
530         String channnelID = SysteminfoBindingConstants.CHANNEL_MEMORY_AVAILABLE;
531         String acceptedItemType = "Number:DataAmount";
532
533         QuantityType<DataAmount> mockedMemoryAvailableValue = new QuantityType<>(1000, Units.MEBIBYTE);
534         when(mockedSystemInfo.getMemoryAvailable()).thenReturn(mockedMemoryAvailableValue);
535
536         initializeThingWithChannel(channnelID, acceptedItemType);
537         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
538                 mockedMemoryAvailableValue);
539     }
540
541     @Test
542     public void assertChannelMemoryUsedIsUpdated() {
543         String channnelID = SysteminfoBindingConstants.CHANNEL_MEMORY_USED;
544         String acceptedItemType = "Number:DataAmount";
545
546         QuantityType<DataAmount> mockedMemoryUsedValue = new QuantityType<>(24, Units.MEBIBYTE);
547         when(mockedSystemInfo.getMemoryUsed()).thenReturn(mockedMemoryUsedValue);
548
549         initializeThingWithChannel(channnelID, acceptedItemType);
550         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedMemoryUsedValue);
551     }
552
553     @Test
554     public void assertChannelMemoryTotalIsUpdated() {
555         String channnelID = SysteminfoBindingConstants.CHANNEL_MEMORY_TOTAL;
556         String acceptedItemType = "Number:DataAmount";
557
558         QuantityType<DataAmount> mockedMemoryTotalValue = new QuantityType<>(1024, Units.MEBIBYTE);
559         when(mockedSystemInfo.getMemoryTotal()).thenReturn(mockedMemoryTotalValue);
560
561         initializeThingWithChannel(channnelID, acceptedItemType);
562         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
563                 mockedMemoryTotalValue);
564     }
565
566     @Test
567     public void assertChannelMemoryAvailablePercentIsUpdated() {
568         String channnelID = SysteminfoBindingConstants.CHANNEL_MEMORY_AVAILABLE_PERCENT;
569         String acceptedItemType = "Number";
570
571         PercentType mockedMemoryAvailablePercentValue = new PercentType(97);
572         when(mockedSystemInfo.getMemoryAvailablePercent()).thenReturn(mockedMemoryAvailablePercentValue);
573
574         initializeThingWithChannel(channnelID, acceptedItemType);
575         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
576                 mockedMemoryAvailablePercentValue);
577     }
578
579     @Test
580     public void assertChannelSwapAvailableIsUpdated() {
581         String channnelID = SysteminfoBindingConstants.CHANNEL_SWAP_AVAILABLE;
582         String acceptedItemType = "Number:DataAmount";
583
584         QuantityType<DataAmount> mockedSwapAvailableValue = new QuantityType<>(482, Units.MEBIBYTE);
585         when(mockedSystemInfo.getSwapAvailable()).thenReturn(mockedSwapAvailableValue);
586
587         initializeThingWithChannel(channnelID, acceptedItemType);
588         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
589                 mockedSwapAvailableValue);
590     }
591
592     @Test
593     public void assertChannelSwapUsedIsUpdated() {
594         String channnelID = SysteminfoBindingConstants.CHANNEL_SWAP_USED;
595         String acceptedItemType = "Number:DataAmount";
596
597         QuantityType<DataAmount> mockedSwapUsedValue = new QuantityType<>(30, Units.MEBIBYTE);
598         when(mockedSystemInfo.getSwapUsed()).thenReturn(mockedSwapUsedValue);
599
600         initializeThingWithChannel(channnelID, acceptedItemType);
601         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedSwapUsedValue);
602     }
603
604     @Test
605     public void assertChannelSwapTotalIsUpdated() {
606         String channnelID = SysteminfoBindingConstants.CHANNEL_SWAP_TOTAL;
607         String acceptedItemType = "Number:DataAmount";
608
609         QuantityType<DataAmount> mockedSwapTotalValue = new QuantityType<>(512, Units.MEBIBYTE);
610         when(mockedSystemInfo.getSwapTotal()).thenReturn(mockedSwapTotalValue);
611
612         initializeThingWithChannel(channnelID, acceptedItemType);
613         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedSwapTotalValue);
614     }
615
616     @Test
617     public void assertChannelSwapAvailablePercentIsUpdated() {
618         String channnelID = SysteminfoBindingConstants.CHANNEL_SWAP_AVAILABLE_PERCENT;
619         String acceptedItemType = "Number";
620
621         PercentType mockedSwapAvailablePercentValue = new PercentType(94);
622         when(mockedSystemInfo.getSwapAvailablePercent()).thenReturn(mockedSwapAvailablePercentValue);
623
624         initializeThingWithChannel(channnelID, acceptedItemType);
625         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
626                 mockedSwapAvailablePercentValue);
627     }
628
629     @Test
630     public void assertChannelStorageNameIsUpdated() throws DeviceNotFoundException {
631         String channnelID = SysteminfoBindingConstants.CHANNEL_STORAGE_NAME;
632         String acceptedItemType = "String";
633
634         StringType mockedStorageName = new StringType("Mocked Storage Name");
635         when(mockedSystemInfo.getStorageName(DEFAULT_DEVICE_INDEX)).thenReturn(mockedStorageName);
636
637         initializeThingWithChannel(channnelID, acceptedItemType);
638         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedStorageName);
639     }
640
641     @Test
642     public void assertChannelStorageTypeIsUpdated() throws DeviceNotFoundException {
643         String channnelID = SysteminfoBindingConstants.CHANNEL_STORAGE_TYPE;
644         String acceptedItemType = "String";
645
646         StringType mockedStorageType = new StringType("Mocked Storage Type");
647         when(mockedSystemInfo.getStorageType(DEFAULT_DEVICE_INDEX)).thenReturn(mockedStorageType);
648
649         initializeThingWithChannel(channnelID, acceptedItemType);
650         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedStorageType);
651     }
652
653     @Test
654     public void assertChannelStorageDescriptionIsUpdated() throws DeviceNotFoundException {
655         String channnelID = SysteminfoBindingConstants.CHANNEL_STORAGE_DESCRIPTION;
656         String acceptedItemType = "String";
657
658         StringType mockedStorageDescription = new StringType("Mocked Storage Description");
659         when(mockedSystemInfo.getStorageDescription(DEFAULT_DEVICE_INDEX)).thenReturn(mockedStorageDescription);
660
661         initializeThingWithChannel(channnelID, acceptedItemType);
662         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
663                 mockedStorageDescription);
664     }
665
666     @Test
667     public void assertChannelStorageAvailableIsUpdated() throws DeviceNotFoundException {
668         String channnelID = SysteminfoBindingConstants.CHANNEL_STORAGE_AVAILABLE;
669         String acceptedItemType = "Number:DataAmount";
670
671         QuantityType<DataAmount> mockedStorageAvailableValue = new QuantityType<>(2000, Units.MEBIBYTE);
672         when(mockedSystemInfo.getStorageAvailable(DEFAULT_DEVICE_INDEX)).thenReturn(mockedStorageAvailableValue);
673
674         initializeThingWithChannel(channnelID, acceptedItemType);
675         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
676                 mockedStorageAvailableValue);
677     }
678
679     @Test
680     public void assertChannelStorageUsedIsUpdated() throws DeviceNotFoundException {
681         String channnelID = SysteminfoBindingConstants.CHANNEL_STORAGE_USED;
682         String acceptedItemType = "Number:DataAmount";
683
684         QuantityType<DataAmount> mockedStorageUsedValue = new QuantityType<>(500, Units.MEBIBYTE);
685         when(mockedSystemInfo.getStorageUsed(DEFAULT_DEVICE_INDEX)).thenReturn(mockedStorageUsedValue);
686
687         initializeThingWithChannel(channnelID, acceptedItemType);
688         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
689                 mockedStorageUsedValue);
690     }
691
692     @Test
693     public void assertChannelStorageTotalIsUpdated() throws DeviceNotFoundException {
694         String channnelID = SysteminfoBindingConstants.CHANNEL_STORAGE_TOTAL;
695         String acceptedItemType = "Number:DataAmount";
696
697         QuantityType<DataAmount> mockedStorageTotalValue = new QuantityType<>(2500, Units.MEBIBYTE);
698         when(mockedSystemInfo.getStorageTotal(DEFAULT_DEVICE_INDEX)).thenReturn(mockedStorageTotalValue);
699
700         initializeThingWithChannel(channnelID, acceptedItemType);
701         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
702                 mockedStorageTotalValue);
703     }
704
705     @Test
706     public void assertChannelStorageAvailablePercentIsUpdated() throws DeviceNotFoundException {
707         String channnelID = SysteminfoBindingConstants.CHANNEL_STORAGE_AVAILABLE_PERCENT;
708         String acceptedItemType = "Number";
709
710         PercentType mockedStorageAvailablePercent = new PercentType(20);
711         when(mockedSystemInfo.getStorageAvailablePercent(DEFAULT_DEVICE_INDEX))
712                 .thenReturn(mockedStorageAvailablePercent);
713
714         initializeThingWithChannel(channnelID, acceptedItemType);
715         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
716                 mockedStorageAvailablePercent);
717     }
718
719     @Test
720     public void assertChannelDriveNameIsUpdated() throws DeviceNotFoundException {
721         String channelID = SysteminfoBindingConstants.CHANNEL_DRIVE_NAME;
722         String acceptedItemType = "String";
723
724         StringType mockedDriveNameValue = new StringType("Mocked Drive Name");
725         when(mockedSystemInfo.getDriveName(DEFAULT_DEVICE_INDEX)).thenReturn(mockedDriveNameValue);
726
727         initializeThingWithChannel(channelID, acceptedItemType);
728         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedDriveNameValue);
729     }
730
731     @Test
732     public void assertChannelDriveModelIsUpdated() throws DeviceNotFoundException {
733         String channelID = SysteminfoBindingConstants.CHANNEL_DRIVE_MODEL;
734         String acceptedItemType = "String";
735
736         StringType mockedDriveModelValue = new StringType("Mocked Drive Model");
737         when(mockedSystemInfo.getDriveModel(DEFAULT_DEVICE_INDEX)).thenReturn(mockedDriveModelValue);
738
739         initializeThingWithChannel(channelID, acceptedItemType);
740         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedDriveModelValue);
741     }
742
743     @Test
744     public void assertChannelDriveSerialIsUpdated() throws DeviceNotFoundException {
745         String channelID = SysteminfoBindingConstants.CHANNEL_DRIVE_SERIAL;
746         String acceptedItemType = "String";
747
748         StringType mockedDriveSerialNumber = new StringType("Mocked Drive Serial Number");
749         when(mockedSystemInfo.getDriveSerialNumber(DEFAULT_DEVICE_INDEX)).thenReturn(mockedDriveSerialNumber);
750
751         initializeThingWithChannel(channelID, acceptedItemType);
752         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
753                 mockedDriveSerialNumber);
754     }
755
756     // Re-enable this previously disabled test, as it is not relying on hardware anymore, but a mocked object
757     // There is a bug opened for this issue - https://github.com/dblock/oshi/issues/185
758     @Test
759     public void assertChannelSensorsCpuTempIsUpdated() {
760         String channnelID = SysteminfoBindingConstants.CHANNEL_SENSORS_CPU_TEMPERATURE;
761         String acceptedItemType = "Number:Temperature";
762
763         QuantityType<Temperature> mockedSensorsCpuTemperatureValue = new QuantityType<>(60, SIUnits.CELSIUS);
764         when(mockedSystemInfo.getSensorsCpuTemperature()).thenReturn(mockedSensorsCpuTemperatureValue);
765
766         initializeThingWithChannel(channnelID, acceptedItemType);
767         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
768                 mockedSensorsCpuTemperatureValue);
769     }
770
771     @Test
772     public void assertChannelSensorsCpuVoltageIsUpdated() {
773         String channnelID = SysteminfoBindingConstants.CHANNEL_SENOSRS_CPU_VOLTAGE;
774         String acceptedItemType = "Number:ElectricPotential";
775
776         QuantityType<ElectricPotential> mockedSensorsCpuVoltageValue = new QuantityType<>(1000, Units.VOLT);
777         when(mockedSystemInfo.getSensorsCpuVoltage()).thenReturn(mockedSensorsCpuVoltageValue);
778
779         initializeThingWithChannel(channnelID, acceptedItemType);
780         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
781                 mockedSensorsCpuVoltageValue);
782     }
783
784     @Test
785     public void assertChannelSensorsFanSpeedIsUpdated() throws DeviceNotFoundException {
786         String channnelID = SysteminfoBindingConstants.CHANNEL_SENSORS_FAN_SPEED;
787         String acceptedItemType = "Number";
788
789         DecimalType mockedSensorsCpuFanSpeedValue = new DecimalType(180);
790         when(mockedSystemInfo.getSensorsFanSpeed(DEFAULT_DEVICE_INDEX)).thenReturn(mockedSensorsCpuFanSpeedValue);
791
792         initializeThingWithChannel(channnelID, acceptedItemType);
793         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
794                 mockedSensorsCpuFanSpeedValue);
795     }
796
797     @Test
798     public void assertChannelBatteryNameIsUpdated() throws DeviceNotFoundException {
799         String channnelID = SysteminfoBindingConstants.CHANNEL_BATTERY_NAME;
800         String acceptedItemType = "String";
801
802         StringType mockedBatteryName = new StringType("Mocked Battery Name");
803         when(mockedSystemInfo.getBatteryName(DEFAULT_DEVICE_INDEX)).thenReturn(mockedBatteryName);
804
805         initializeThingWithChannel(channnelID, acceptedItemType);
806         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedBatteryName);
807     }
808
809     @Test
810     public void assertChannelBatteryRemainingCapacityIsUpdated() throws DeviceNotFoundException {
811         String channnelID = SysteminfoBindingConstants.CHANNEL_BATTERY_REMAINING_CAPACITY;
812         String acceptedItemType = "Number";
813
814         PercentType mockedBatteryRemainingCapacity = new PercentType(20);
815         when(mockedSystemInfo.getBatteryRemainingCapacity(DEFAULT_DEVICE_INDEX))
816                 .thenReturn(mockedBatteryRemainingCapacity);
817
818         initializeThingWithChannel(channnelID, acceptedItemType);
819         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
820                 mockedBatteryRemainingCapacity);
821     }
822
823     @Test
824     public void assertChannelBatteryRemainingTimeIsUpdated() throws DeviceNotFoundException {
825         String channnelID = SysteminfoBindingConstants.CHANNEL_BATTERY_REMAINING_TIME;
826         String acceptedItemType = "Number:Time";
827
828         QuantityType<Time> mockedBatteryRemainingTime = new QuantityType<>(3600, Units.MINUTE);
829         when(mockedSystemInfo.getBatteryRemainingTime(DEFAULT_DEVICE_INDEX)).thenReturn(mockedBatteryRemainingTime);
830
831         initializeThingWithChannel(channnelID, acceptedItemType);
832         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
833                 mockedBatteryRemainingTime);
834     }
835
836     @Test
837     public void assertChannelDisplayInformationIsUpdated() throws DeviceNotFoundException {
838         String channnelID = SysteminfoBindingConstants.CHANNEL_DISPLAY_INFORMATION;
839         String acceptedItemType = "String";
840
841         StringType mockedDisplayInfo = new StringType("Mocked Display Information");
842         when(mockedSystemInfo.getDisplayInformation(DEFAULT_DEVICE_INDEX)).thenReturn(mockedDisplayInfo);
843
844         initializeThingWithChannel(channnelID, acceptedItemType);
845         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedDisplayInfo);
846     }
847
848     @Test
849     public void assertChannelNetworkIpIsUpdated() throws DeviceNotFoundException {
850         String channnelID = SysteminfoBindingConstants.CHANNEL_NETWORK_IP;
851         String acceptedItemType = "String";
852
853         StringType mockedNetworkIp = new StringType("192.168.1.0");
854         when(mockedSystemInfo.getNetworkIp(DEFAULT_DEVICE_INDEX)).thenReturn(mockedNetworkIp);
855
856         initializeThingWithChannel(channnelID, acceptedItemType);
857         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedNetworkIp);
858     }
859
860     @Test
861     public void assertChannelNetworkMacIsUpdated() throws DeviceNotFoundException {
862         String channnelID = SysteminfoBindingConstants.CHANNEL_NETWORK_MAC;
863         String acceptedItemType = "String";
864
865         StringType mockedNetworkMacValue = new StringType("AB-10-11-12-13-14");
866         when(mockedSystemInfo.getNetworkMac(DEFAULT_DEVICE_INDEX)).thenReturn(mockedNetworkMacValue);
867
868         initializeThingWithChannel(channnelID, acceptedItemType);
869         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedNetworkMacValue);
870     }
871
872     @Test
873     public void assertChannelNetworkDataSentIsUpdated() throws DeviceNotFoundException {
874         String channnelID = SysteminfoBindingConstants.CHANNEL_NETWORK_DATA_SENT;
875         String acceptedItemType = "Number:DataAmount";
876
877         QuantityType<DataAmount> mockedNetworkDataSent = new QuantityType<>(1000, Units.MEBIBYTE);
878         when(mockedSystemInfo.getNetworkDataSent(DEFAULT_DEVICE_INDEX)).thenReturn(mockedNetworkDataSent);
879
880         initializeThingWithChannel(channnelID, acceptedItemType);
881         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedNetworkDataSent);
882     }
883
884     @Test
885     public void assertChannelNetworkDataReceivedIsUpdated() throws DeviceNotFoundException {
886         String channnelID = SysteminfoBindingConstants.CHANNEL_NETWORK_DATA_RECEIVED;
887         String acceptedItemType = "Number:DataAmount";
888
889         QuantityType<DataAmount> mockedNetworkDataReceiveed = new QuantityType<>(800, Units.MEBIBYTE);
890         when(mockedSystemInfo.getNetworkDataReceived(DEFAULT_DEVICE_INDEX)).thenReturn(mockedNetworkDataReceiveed);
891
892         initializeThingWithChannel(channnelID, acceptedItemType);
893         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
894                 mockedNetworkDataReceiveed);
895     }
896
897     @Test
898     public void assertChannelNetworkPacketsSentIsUpdated() throws DeviceNotFoundException {
899         String channnelID = SysteminfoBindingConstants.CHANNEL_NETWORK_PACKETS_SENT;
900         String acceptedItemType = "Number";
901
902         DecimalType mockedNetworkPacketsSent = new DecimalType(50);
903         when(mockedSystemInfo.getNetworkPacketsSent(DEFAULT_DEVICE_INDEX)).thenReturn(mockedNetworkPacketsSent);
904
905         initializeThingWithChannel(channnelID, acceptedItemType);
906         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
907                 mockedNetworkPacketsSent);
908     }
909
910     @Test
911     public void assertChannelNetworkPacketsReceivedIsUpdated() throws DeviceNotFoundException {
912         String channnelID = SysteminfoBindingConstants.CHANNEL_NETWORK_PACKETS_RECEIVED;
913         String acceptedItemType = "Number";
914
915         DecimalType mockedNetworkPacketsReceived = new DecimalType(48);
916         when(mockedSystemInfo.getNetworkPacketsReceived(DEFAULT_DEVICE_INDEX)).thenReturn(mockedNetworkPacketsReceived);
917
918         initializeThingWithChannel(channnelID, acceptedItemType);
919         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
920                 mockedNetworkPacketsReceived);
921     }
922
923     @Test
924     public void assertChannelNetworkNetworkNameIsUpdated() throws DeviceNotFoundException {
925         String channnelID = SysteminfoBindingConstants.CHANNEL_NETWORK_NAME;
926         String acceptedItemType = "String";
927
928         StringType mockedNetworkName = new StringType("MockN-AQ34");
929         when(mockedSystemInfo.getNetworkName(DEFAULT_DEVICE_INDEX)).thenReturn(mockedNetworkName);
930
931         initializeThingWithChannel(channnelID, acceptedItemType);
932         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedNetworkName);
933     }
934
935     @Test
936     public void assertChannelNetworkNetworkDisplayNameIsUpdated() throws DeviceNotFoundException {
937         String channnelID = SysteminfoBindingConstants.CHANNEL_NETWORK_ADAPTER_NAME;
938         String acceptedItemType = "String";
939
940         StringType mockedNetworkAdapterName = new StringType("Mocked Network Adapter Name");
941         when(mockedSystemInfo.getNetworkDisplayName(DEFAULT_DEVICE_INDEX)).thenReturn(mockedNetworkAdapterName);
942
943         initializeThingWithChannel(channnelID, acceptedItemType);
944         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
945                 mockedNetworkAdapterName);
946     }
947
948     class SysteminfoDiscoveryServiceMock extends SysteminfoDiscoveryService {
949         String hostname;
950
951         SysteminfoDiscoveryServiceMock(String hostname) {
952             super();
953             this.hostname = hostname;
954         }
955
956         @Override
957         protected String getHostName() throws UnknownHostException {
958             if ("unresolved".equals(hostname)) {
959                 throw new UnknownHostException();
960             }
961             return hostname;
962         }
963
964         @Override
965         public void startScan() {
966             super.startScan();
967         }
968     }
969
970     @Test
971     public void testDiscoveryWithInvalidHostname() {
972         String hostname = "Hilo.fritz.box";
973         String expectedHostname = "Hilo_fritz_box";
974
975         testDiscoveryService(expectedHostname, hostname);
976     }
977
978     @Test
979     public void testDiscoveryWithValidHostname() {
980         String hostname = "MyComputer";
981         String expectedHostname = "MyComputer";
982
983         testDiscoveryService(expectedHostname, hostname);
984     }
985
986     @Test
987     public void testDiscoveryWithUnresolvedHostname() {
988         String hostname = "unresolved";
989         String expectedHostname = SysteminfoDiscoveryService.DEFAULT_THING_ID;
990
991         testDiscoveryService(expectedHostname, hostname);
992     }
993
994     @Test
995     public void testDiscoveryWithEmptyHostnameString() {
996         String hostname = "";
997         String expectedHostname = SysteminfoDiscoveryService.DEFAULT_THING_ID;
998
999         testDiscoveryService(expectedHostname, hostname);
1000     }
1001
1002     private void testDiscoveryService(String expectedHostname, String hostname) {
1003         SysteminfoDiscoveryService discoveryService = getService(DiscoveryService.class,
1004                 SysteminfoDiscoveryService.class);
1005         waitForAssert(() -> {
1006             assertThat(discoveryService, is(notNullValue()));
1007         });
1008         SysteminfoDiscoveryServiceMock discoveryServiceMock = new SysteminfoDiscoveryServiceMock(hostname);
1009         if (discoveryService != null) {
1010             unregisterService(DiscoveryService.class);
1011         }
1012         registerService(discoveryServiceMock, DiscoveryService.class.getName(), new Hashtable<>());
1013
1014         ThingTypeUID computerType = SysteminfoBindingConstants.THING_TYPE_COMPUTER;
1015         ThingUID computerUID = new ThingUID(computerType, expectedHostname);
1016
1017         discoveryServiceMock.startScan();
1018
1019         Inbox inbox = getService(Inbox.class);
1020         waitForAssert(() -> {
1021             assertThat(inbox, is(notNullValue()));
1022         });
1023
1024         if (inbox == null) {
1025             return;
1026         }
1027
1028         waitForAssert(() -> {
1029             List<DiscoveryResult> results = inbox.stream().filter(InboxPredicates.forThingUID(computerUID)).toList();
1030             assertFalse(results.isEmpty(), "No Thing with UID " + computerUID.getAsString() + " in inbox");
1031         });
1032
1033         inbox.approve(computerUID, SysteminfoDiscoveryService.DEFAULT_THING_LABEL, null);
1034
1035         waitForAssert(() -> {
1036             systeminfoThing = thingRegistry.get(computerUID);
1037             assertThat(systeminfoThing, is(notNullValue()));
1038         });
1039
1040         Thing thing = systeminfoThing;
1041         if (thing == null) {
1042             return;
1043         }
1044
1045         waitForAssert(() -> {
1046             assertThat("Thing is not initialized.", thing.getStatus(), is(equalTo(ThingStatus.ONLINE)));
1047         });
1048     }
1049
1050     @Test
1051     public void assertChannelProcessThreadsIsUpdatedWithPIDse() throws DeviceNotFoundException {
1052         String channnelID = SysteminfoBindingConstants.CHANNEL_PROCESS_THREADS;
1053         String acceptedItemType = "Number";
1054         // The pid of the System idle process in Windows
1055         int pid = 0;
1056
1057         DecimalType mockedProcessThreadsCount = new DecimalType(4);
1058         when(mockedSystemInfo.getProcessThreads(pid)).thenReturn(mockedProcessThreadsCount);
1059
1060         initializeThingWithChannelAndPID(channnelID, acceptedItemType, pid);
1061         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY,
1062                 mockedProcessThreadsCount);
1063     }
1064
1065     @Test
1066     public void assertChannelProcessPathIsUpdatedWithPIDset() throws DeviceNotFoundException {
1067         String channnelID = SysteminfoBindingConstants.CHANNEL_PROCESS_PATH;
1068         String acceptedItemType = "String";
1069         // The pid of the System idle process in Windows
1070         int pid = 0;
1071
1072         StringType mockedProcessPath = new StringType("C:\\Users\\MockedUser\\Process");
1073         when(mockedSystemInfo.getProcessPath(pid)).thenReturn(mockedProcessPath);
1074
1075         initializeThingWithChannelAndPID(channnelID, acceptedItemType, pid);
1076         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedProcessPath);
1077     }
1078
1079     @Test
1080     public void assertChannelProcessNameIsUpdatedWithPIDset() throws DeviceNotFoundException {
1081         String channnelID = SysteminfoBindingConstants.CHANNEL_PROCESS_NAME;
1082         String acceptedItemType = "String";
1083         // The pid of the System idle process in Windows
1084         int pid = 0;
1085
1086         StringType mockedProcessName = new StringType("MockedProcess.exe");
1087         when(mockedSystemInfo.getProcessName(pid)).thenReturn(mockedProcessName);
1088
1089         initializeThingWithChannelAndPID(channnelID, acceptedItemType, pid);
1090         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedProcessName);
1091     }
1092
1093     @Test
1094     public void assertChannelProcessMemoryIsUpdatedWithPIDset() throws DeviceNotFoundException {
1095         String channnelID = SysteminfoBindingConstants.CHANNEL_PROCESS_MEMORY;
1096         String acceptedItemType = "Number:DataAmount";
1097         // The pid of the System idle process in Windows
1098         int pid = 0;
1099
1100         QuantityType<DataAmount> mockedProcessMemory = new QuantityType<>(450, Units.MEBIBYTE);
1101         when(mockedSystemInfo.getProcessMemoryUsage(pid)).thenReturn(mockedProcessMemory);
1102
1103         initializeThingWithChannelAndPID(channnelID, acceptedItemType, pid);
1104         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedProcessMemory);
1105     }
1106
1107     @Test
1108     public void assertChannelProcessLoadIsUpdatedWithPIDset() throws DeviceNotFoundException {
1109         String channnelID = SysteminfoBindingConstants.CHANNEL_PROCESS_LOAD;
1110         String acceptedItemType = "Number";
1111         // The pid of the System idle process in Windows
1112         int pid = 0;
1113
1114         DecimalType mockedProcessLoad = new DecimalType(3);
1115         when(mockedSystemInfo.getProcessCpuUsage(pid)).thenReturn(mockedProcessLoad);
1116
1117         initializeThingWithChannelAndPID(channnelID, acceptedItemType, pid);
1118         assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedProcessLoad);
1119     }
1120
1121     @Test
1122     public void testThingHandlesChannelPriorityChange() {
1123         String priorityKey = "priority";
1124         String pidKey = "pid";
1125         String initialPriority = DEFAULT_CHANNEL_TEST_PRIORITY; // Evaluates to High
1126         String newPriority = "Low";
1127
1128         String acceptedItemType = "Number";
1129         initializeThingWithChannel(DEFAULT_TEST_CHANNEL_ID, acceptedItemType);
1130
1131         Thing thing = systeminfoThing;
1132         if (thing == null) {
1133             throw new AssertionError("Thing is null");
1134         }
1135         Channel channel = thing.getChannel(DEFAULT_TEST_CHANNEL_ID);
1136         if (channel == null) {
1137             throw new AssertionError("Channel '" + DEFAULT_TEST_CHANNEL_ID + "' is null");
1138         }
1139
1140         ThingHandler thingHandler = thing.getHandler();
1141         if (thingHandler == null) {
1142             throw new AssertionError("Thing handler is null");
1143         }
1144         if (!(thingHandler.getClass().equals(SysteminfoHandler.class))) {
1145             throw new AssertionError("Thing handler not of class SysteminfoHandler");
1146         }
1147         SysteminfoHandler handler = (SysteminfoHandler) thingHandler;
1148         waitForAssert(() -> {
1149             assertThat("The initial priority of channel " + channel.getUID() + " is not as expected.",
1150                     channel.getConfiguration().get(priorityKey), is(equalTo(initialPriority)));
1151             assertThat(handler.getHighPriorityChannels().contains(channel.getUID()), is(true));
1152         });
1153
1154         // Change the priority of a channel, keep the pid
1155         Configuration updatedConfig = new Configuration();
1156         updatedConfig.put(priorityKey, newPriority);
1157         updatedConfig.put(pidKey, channel.getConfiguration().get(pidKey));
1158         Channel updatedChannel = ChannelBuilder.create(channel.getUID(), channel.getAcceptedItemType())
1159                 .withType(channel.getChannelTypeUID()).withKind(channel.getKind()).withConfiguration(updatedConfig)
1160                 .build();
1161
1162         Thing updatedThing = ThingBuilder.create(thing.getThingTypeUID(), thing.getUID())
1163                 .withConfiguration(thing.getConfiguration()).withChannel(updatedChannel).build();
1164
1165         handler.thingUpdated(updatedThing);
1166
1167         waitForAssert(() -> {
1168             assertThat("The prority of the channel was not updated: ", channel.getConfiguration().get(priorityKey),
1169                     is(equalTo(newPriority)));
1170             assertThat(handler.getLowPriorityChannels().contains(channel.getUID()), is(true));
1171         });
1172     }
1173 }