APIs are central to the Internet of Things (IoT). DevTest is an extremely capable API testing tool. Many corporate organisations are already implementing IoT devices, such as set-top boxes (STBs), smart meters, point-of-sale devices, etc, and even more are developing software to run in an IoT infrastructure, like banking apps.
Over the past couple of days, I've been looking at my home network with regard to IoT. I didn't think I had much call for management, but I find that my home LAN includes:
2 SKY+HD STBs
3 Roku LT players
3 Nest smoke alarms
Panasonic wifi speakers
Sound bar, subwoofer & 2 satellite speakers for the lounge TV
2 speakers in the basement allocated to L and R channels for immersive music
1 speaker in both of the 1st floor bedrooms
BG Hive hub
Zigbee master thermostat
Zigbee boiler & water tank controller
LAN servers
WD myBookWorld, originally for iTKO backups, but now running a version of Debian Linux
Amahi home server for DNS, DHCP, network shares, etc
Proxmox virtualised server platform
Plex software for networked video
Logitech Squeeze Server software for networked audio
My wife's business website server at http://www.ena-marine.co.uk
Nessus for LAN security
etc
1 Panasonic wifi landline phone
1 Panasonic smart TV
1 Samsung wifi blu-ray player
1 Epson wifi printer
1 BT Home Hub 5 wifi router
1 Thomson wifi access point (powerline ethernet to wifi router)
1 Nintendo Wii
1 Android tablet
5 Android phones
1 iPhone
1 Windows laptop
2 Mac laptops
1 nettop PC to explore low-power media player software
All of this stuff needs monitoring, so I'm wondering whether CA UIM would be useful, or if I would do better completing my evaluation of openHAB which seems to be designed for IoT monitoring, but everything has also been tested and continues to need testing, and I know that the software release cycle for my smoke alarms is different to that of my speakers, because they auto-upgrade at different times.
Someone must be testing all the APIs contained in each of the devices. Every device is a server, and every one of them communicates over the LAN, some upstream to b2c servers, some downstream to clients on my LAN. For example, my personal mobile phone includes the Panasonic Smart Phone app to take landline calls, the Plex client to watch my classic Doctor Who collection, the Nest app to alert me when I'm burning dinner again (for details, visit http://cookerydisasters.blogspot.co.uk), the Hive app to turn the heating on because Summer still hasn't arrived (it's JULY already!), and many others.
So, as I said, every device is a server. Servers need APIs. What, where and how could an API work for my speakers, for example? Well, I noticed that, when I start the Panasonic music player app on my phone, it forces me to wait for a few seconds before it shows all my speakers. There must be some discovery happening on my network, and network discovery is something that I should be able to accomplish in DevTest, in preparation for querying and updating via standard APIs.
LAN discovery is generally accomplished by querying using "Simple Service Discovery Protocol" (ssdp), enhanced by Universal Plug'n'Play (uPnP), using multicast HTTP (HTTP over UDP, not over TCP). UDP is a strange protocol. There's no point in properly performance testing UDP, because servers advertise when they are initially connected and then repeat the advertisement at their expire time. Clients send a discovery query with a timeout, and the functional specification for ssdp says that every server must respond with a message for every service it provides before the timeout period is reached. Network load is directly proportional to the number of services advertised on the LAN multiplied by the number of client requests over time, but because there is no direct connection between clients and servers, there is no way to test dropped messages or to assert on errors. Therefore, it's simply a measure of network traffic, and doesn't need a testing tool.
So, what about functional testing? Specifically, how would a query be performed that will provide a response that can be used as a part of a business process? It might be best to show a client discovery request and a response.
Request:
M-SEARCH * HTTP/1.1
Host: 239.255.255.250:1900
MX: 5
Man: "ssdp:discover"
ST: ssdp:all
Note the blank line at the end of the request.
Sample response:
INFO - NOTIFY * HTTP/1.1
INFO - Host: 239.255.255.250:1900
INFO - Cache-Control: max-age=1800
INFO - Location: http://192.168.1.165:2870/dmr.xml
INFO - NT: urn:schemas-upnp-org:service:RenderingControl:1
INFO - NTS: ssdp:alive
INFO - Server: NFLC/2.3 UPnP/1.0 DLNADOC/1.50
INFO - USN: uuid:12345678-1234-1234-1234-123456789abc::urn:schemas-upnp-org:service:RenderingControl:1
This response provides us some useful information. Interesting things for this specific response might be:
It contains a URL, which we can then use to query the server
It is a RenderingControl, so it's something to do with media
It is DLNA, so it conforms to the Digital Living Network Alliance operability guidelines for media appliances
Navigating to the URL provided gives this response:
<root>
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<device>
<dlna:X_DLNADOC>DMR-1.50</dlna:X_DLNADOC>
<dlna:X_DLNACAP/>
<deviceType>urn:schemas-upnp-org:device:MediaRenderer:1</deviceType>
<friendlyName>KitchenR</friendlyName>
<manufacturer>Qualcomm AllPlay</manufacturer>
<manufacturerURL>http://www.qualcomm.com</manufacturerURL>
<modelDescription>AllPlay capable network audio module.</modelDescription>
<modelName>SamAudio</modelName>
<modelNumber>CUS227 1.0</modelNumber>
further details snipped
So we can see that this is one of my Panasonic speakers; specifically, the one allocated to the right stereo channel in the Kitchen.
Ok, so that is an example of the data format, now start doing it in DevTest! So far, I have been looking at this in my spare time this weekend around the sport, and there has been a LOT of sport on TV: Euro2016 football, ODI cricket, Wimbledon, Tour de France, F1 GP, etc, so I have implemented a simple ssdp test step in bean shell, adapted from something I found on the Internet
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketTimeoutException;
/**
* UPNP/SSDP client to demonstrate the usage of UDP multicast sockets.
*
* @throws IOException
*/
public void multicast() throws IOException {
int numberOfResponses = 0;
try {
InetAddress multicastAddress = InetAddress.getByName("239.255.255.250");
// multicast address for SSDP
final int port = 1900; // standard port for SSDP
MulticastSocket socket = new MulticastSocket(port);
socket.setReuseAddress(true);
socket.setSoTimeout(15000);
socket.joinGroup(multicastAddress);
// send discover
byte[] txbuf = DISCOVER_MESSAGE.getBytes("UTF-8");
DatagramPacket hi = new DatagramPacket(txbuf, txbuf.length,
multicastAddress, port);
socket.send(hi);
_logger.debug("SSDP discover sent");
do {
byte[] rxbuf = new byte[8192];
DatagramPacket packet = new DatagramPacket(rxbuf, rxbuf.length);
socket.receive(packet);
dumpPacket(packet);
numberOfResponses++;
} while (true); // should leave loop by SocketTimeoutException
} catch (SocketTimeoutException e) {
_logger.debug("Multicast timed out after {} responses", numberOfResponses);
}
}
private void dumpPacket(DatagramPacket packet) throws IOException {
InetAddress addr = packet.getAddress();
_logger.debug("Response from: {}", addr);
ByteArrayInputStream in = new ByteArrayInputStream(packet.getData(), 0, packet.getLength());
copyStream(in, System.out);
}
private void copyStream(InputStream in, OutputStream out) throws IOException {
BufferedInputStream bin = new BufferedInputStream(in);
BufferedOutputStream bout = new BufferedOutputStream(out);
int c = bin.read();
while (c != -1) {
out.write((char) c);
c = bin.read();
}
bout.flush();
}
private final static String DISCOVER_MESSAGE
= "M-SEARCH * HTTP/1.1\r\n"
+ "HOST: 239.255.255.250:1900\r\n"
+ "MAN: \"ssdp:discover\"\r\n"
+ "MX: 5\r\n"
+ "ST: ssdp:all\r\n"
+ "\r\n";
multicast();
Run this step and it'll spend a good few seconds being unresponsive, but it'll eventually complete with a large amount of logging, showing all (well, perhaps not all - it depends on how well your servers respond to discovery messages) your ssdp & upnp servers on your network.