[AETHER-2613]: Improve Ping Test of Monitoring Agent

Ping entries added (taken from ping command output):
  - transmitted: The number of packets transmitted.
  - received: The number of packets received.
  - median: The median of all successful rtt packet times in ms.

Adds support for running ping to+from:
  - management_server
  - dry_run: Should be first to run since first ping test after attach may drop packets. Runs 3 iterations.

Also changes default DNS to 1.1.1.1

Change-Id: I796ce1bd88510282703e9400a69cf5df31f9fc53
diff --git a/VERSION b/VERSION
index 6769f67..faef31a 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.6.15
+0.7.0
diff --git a/edge-monitoring-server/edge_monitoring_server.py b/edge-monitoring-server/edge_monitoring_server.py
index f9184d8..0110e34 100755
--- a/edge-monitoring-server/edge_monitoring_server.py
+++ b/edge-monitoring-server/edge_monitoring_server.py
@@ -61,9 +61,25 @@
                 "ping": {
                     "type": "object",
                     "properties": {
+                        "dry_run": {
+                            "type": "object",
+                            "properties": {
+                                "transmitted": {"type": "number"},
+                                "received": {"type": "number"},
+                                "median": {"type": "number"},
+                                "min": {"type": "number"},
+                                "avg": {"type": "number"},
+                                "max": {"type": "number"},
+                                "stddev": {"type": "number"}
+                            },
+                            "required": ["min", "avg", "max", "stddev"]
+                        },
                         "dns": {
                             "type": "object",
                             "properties": {
+                                "transmitted": {"type": "number"},
+                                "received": {"type": "number"},
+                                "median": {"type": "number"},
                                 "min": {"type": "number"},
                                 "avg": {"type": "number"},
                                 "max": {"type": "number"},
@@ -74,13 +90,29 @@
                         "iperf_server": {
                             "type": "object",
                             "properties": {
+                                "transmitted": {"type": "number"},
+                                "received": {"type": "number"},
+                                "median": {"type": "number"},
                                 "min": {"type": "number"},
                                 "avg": {"type": "number"},
                                 "max": {"type": "number"},
                                 "stddev": {"type": "number"}
                             },
                             "required": ["min", "avg", "max", "stddev"]
-                        }
+                        },
+                        "management_server": {
+                            "type": "object",
+                            "properties": {
+                                "transmitted": {"type": "number"},
+                                "received": {"type": "number"},
+                                "median": {"type": "number"},
+                                "min": {"type": "number"},
+                                "avg": {"type": "number"},
+                                "max": {"type": "number"},
+                                "stddev": {"type": "number"}
+                            },
+                            "required": ["min", "avg", "max", "stddev"]
+                        },
                     }
                 },
                 "iperf": {
@@ -119,13 +151,37 @@
         },
         'speedtest': {
             'ping': {
+                'dry_run': {
+                    'transmitted': 0,
+                    'received': 0,
+                    'median': 0.0,
+                    'min': 0.0,
+                    'avg': 0.0,
+                    'max': 0.0,
+                    'stddev': 0.0
+                },
                 'dns': {
+                    'transmitted': 0,
+                    'received': 0,
+                    'median': 0.0,
                     'min': 0.0,
                     'avg': 0.0,
                     'max': 0.0,
                     'stddev': 0.0
                 },
                 'iperf_server': {
+                    'transmitted': 0,
+                    'received': 0,
+                    'median': 0.0,
+                    'min': 0.0,
+                    'avg': 0.0,
+                    'max': 0.0,
+                    'stddev': 0.0
+                },
+                'management_server': {
+                    'transmitted': 0,
+                    'received': 0,
+                    'median': 0.0,
                     'min': 0.0,
                     'avg': 0.0,
                     'max': 0.0,
@@ -170,18 +226,42 @@
 ping_test_ok = prom.Gauge("aetheredge_ping_test_ok", "Last ping test passed", ["name"])
 e2e_tests_down = prom.Gauge("aetheredge_e2e_tests_down", "E2E tests not reporting", ["name"])
 
-# Speedtest dns ping metrics
+# Ping dry_run metrics
+ping_dry_run_transmitted = prom.Gauge("aetheredge_ping_dry_run_test_transmitted","Last ping test to dry_run number of transmitted packets",["name"])
+ping_dry_run_received = prom.Gauge("aetheredge_ping_dry_run_test_received","Last ping test to dry_run number of received packets",["name"])
+ping_dry_run_median = prom.Gauge("aetheredge_ping_dry_run_test_median","Last ping test to dry_run median value",["name"])
+ping_dry_run_min = prom.Gauge("aetheredge_ping_dry_run_test_min","Last ping test to dry_run minimum value",["name"])
+ping_dry_run_avg = prom.Gauge("aetheredge_ping_dry_run_test_avg","Last ping test to dry_run average",["name"])
+ping_dry_run_max = prom.Gauge("aetheredge_ping_dry_run_test_max","Last ping test to dry_run maximum value",["name"])
+ping_dry_run_stddev = prom.Gauge("aetheredge_ping_dry_run_test_stddev","Last ping test to dry_run standard deviation",["name"])
+
+# Ping dns metrics
+ping_dns_transmitted = prom.Gauge("aetheredge_ping_dns_test_transmitted","Last ping test to dns number of transmitted packets",["name"])
+ping_dns_received = prom.Gauge("aetheredge_ping_dns_test_received","Last ping test to dns number of received packets",["name"])
+ping_dns_median = prom.Gauge("aetheredge_ping_dns_test_median","Last ping test to dns median value",["name"])
 ping_dns_min = prom.Gauge("aetheredge_ping_dns_test_min","Last ping test to dns minimum value",["name"])
 ping_dns_avg = prom.Gauge("aetheredge_ping_dns_test_avg","Last ping test to dns average",["name"])
 ping_dns_max = prom.Gauge("aetheredge_ping_dns_test_max","Last ping test to dns maximum value",["name"])
 ping_dns_stddev = prom.Gauge("aetheredge_ping_dns_test_stddev","Last ping test to dns standard deviation",["name"])
 
-# Speedtest iperf server ping metrics
+# Ping iperf server metrics
+ping_iperf_server_transmitted = prom.Gauge("aetheredge_ping_iperf_server_test_transmitted","Last ping test to iperf_server number of transmitted packets",["name"])
+ping_iperf_server_received = prom.Gauge("aetheredge_ping_iperf_server_test_received","Last ping test to iperf_server number of received packets",["name"])
+ping_iperf_server_median = prom.Gauge("aetheredge_ping_iperf_server_test_median","Last ping test to iperf_server median value",["name"])
 ping_iperf_server_min = prom.Gauge("aetheredge_ping_iperf_server_test_min","Last ping test to iperf_server minimum value",["name"])
 ping_iperf_server_avg = prom.Gauge("aetheredge_ping_iperf_server_test_avg","Last ping test to iperf_server average",["name"])
 ping_iperf_server_max = prom.Gauge("aetheredge_ping_iperf_server_test_max","Last ping test to iperf_server maximum value",["name"])
 ping_iperf_server_stddev = prom.Gauge("aetheredge_ping_iperf_server_test_stddev","Last ping test to iperf_server standard deviation",["name"])
 
+# Ping management_server metrics
+ping_management_server_transmitted = prom.Gauge("aetheredge_ping_management_server_test_transmitted","Last ping test to management_server number of transmitted packets",["name"])
+ping_management_server_received = prom.Gauge("aetheredge_ping_management_server_test_received","Last ping test to management_server number of received packets",["name"])
+ping_management_server_median = prom.Gauge("aetheredge_ping_management_server_test_median","Last ping test to management_server median value",["name"])
+ping_management_server_min = prom.Gauge("aetheredge_ping_management_server_test_min","Last ping test to management_server minimum value",["name"])
+ping_management_server_avg = prom.Gauge("aetheredge_ping_management_server_test_avg","Last ping test to management_server average",["name"])
+ping_management_server_max = prom.Gauge("aetheredge_ping_management_server_test_max","Last ping test to management_server maximum value",["name"])
+ping_management_server_stddev = prom.Gauge("aetheredge_ping_management_server_test_stddev","Last ping test to management_server standard deviation",["name"])
+
 # Speedtest iperf metrics
 iperf_cluster_downlink = prom.Gauge("aetheredge_iperf_cluster_downlink_test","Last iperf test downlink result",["name"])
 iperf_cluster_uplink = prom.Gauge("aetheredge_iperf_cluster_uplink_test","Last iperf test downlink result",["name"])
@@ -249,14 +329,34 @@
         if time_elapsed > NO_RESULT_THRESHOLD:
             edge['status']['control_plane'] = "no result"
             edge['status']['user_plane'] = "no result"
-            edge['speedtest']['ping']['dns'] = {'min': 0.0,
+            edge['speedtest']['ping']['dry_run'] = {'transmitted': 0,
+                                                    'received': 0,
+                                                    'median': 0.0,
+                                                    'min': 0.0,
+                                                    'avg': 0.0,
+                                                    'max': 0.0,
+                                                    'stddev': 0.0}
+            edge['speedtest']['ping']['dns'] = {'transmitted': 0,
+                                                'received': 0,
+                                                'median': 0.0,
+                                                'min': 0.0,
                                                 'avg': 0.0,
                                                 'max': 0.0,
                                                 'stddev': 0.0}
-            edge['speedtest']['ping']['iperf_server'] = {'min': 0.0,
+            edge['speedtest']['ping']['iperf_server'] = {'transmitted': 0,
+                                                         'received': 0,
+                                                         'median': 0.0,
+                                                         'min': 0.0,
                                                          'avg': 0.0,
                                                          'max': 0.0,
                                                          'stddev': 0.0}
+            edge['speedtest']['ping']['management_server'] = {'transmitted': 0,
+                                                              'received': 0,
+                                                              'median': 0.0,
+                                                              'min': 0.0,
+                                                              'avg': 0.0,
+                                                              'max': 0.0,
+                                                              'stddev': 0.0}
             edge['speedtest']['iperf'] = {'cluster': {
                                             'downlink': 0.0,
                                             'uplink': 0.0
@@ -277,10 +377,24 @@
         pass
 
     try:
+        ping_dry_run_min.remove(name)
+        ping_dry_run_avg.remove(name)
+        ping_dry_run_max.remove(name)
+        ping_dry_run_stddev.remove(name)
+        ping_dry_run_transmitted.remove(name)
+        ping_dry_run_received.remove(name)
+        ping_dry_run_median.remove(name)
+    except:
+        pass
+
+    try:
         ping_dns_min.remove(name)
         ping_dns_avg.remove(name)
         ping_dns_max.remove(name)
         ping_dns_stddev.remove(name)
+        ping_dns_transmitted.remove(name)
+        ping_dns_received.remove(name)
+        ping_dns_median.remove(name)
     except:
         pass
 
@@ -289,6 +403,20 @@
         ping_iperf_server_avg.remove(name)
         ping_iperf_server_max.remove(name)
         ping_iperf_server_stddev.remove(name)
+        ping_iperf_server_transmitted.remove(name)
+        ping_iperf_server_received.remove(name)
+        ping_iperf_server_median.remove(name)
+    except:
+        pass
+
+    try:
+        ping_management_server_min.remove(name)
+        ping_management_server_avg.remove(name)
+        ping_management_server_max.remove(name)
+        ping_management_server_stddev.remove(name)
+        ping_management_server_transmitted.remove(name)
+        ping_management_server_received.remove(name)
+        ping_management_server_median.remove(name)
     except:
         pass
 
@@ -320,6 +448,19 @@
         connect_status = edge['status']['control_plane']
         ping_status = edge['status']['user_plane']
 
+        # Add ping dry_run latency results if available
+        try:
+            if edge['speedtest']['ping']['dry_run']['avg']:
+                ping_dry_run_min.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['min'])
+                ping_dry_run_avg.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['avg'])
+                ping_dry_run_max.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['max'])
+                ping_dry_run_stddev.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['stddev'])
+                ping_dry_run_transmitted.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['transmitted'])
+                ping_dry_run_received.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['received'])
+                ping_dry_run_median.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['median'])
+        except KeyError:
+            pass
+
         # Add ping dns latency results if available
         try:
             if edge['speedtest']['ping']['dns']['avg']:
@@ -327,6 +468,9 @@
                 ping_dns_avg.labels(edge['name']).set(edge['speedtest']['ping']['dns']['avg'])
                 ping_dns_max.labels(edge['name']).set(edge['speedtest']['ping']['dns']['max'])
                 ping_dns_stddev.labels(edge['name']).set(edge['speedtest']['ping']['dns']['stddev'])
+                ping_dns_transmitted.labels(edge['name']).set(edge['speedtest']['ping']['dns']['transmitted'])
+                ping_dns_received.labels(edge['name']).set(edge['speedtest']['ping']['dns']['received'])
+                ping_dns_median.labels(edge['name']).set(edge['speedtest']['ping']['dns']['median'])
         except KeyError:
             pass
 
@@ -337,6 +481,22 @@
                 ping_iperf_server_avg.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['avg'])
                 ping_iperf_server_max.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['max'])
                 ping_iperf_server_stddev.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['stddev'])
+                ping_iperf_server_transmitted.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['transmitted'])
+                ping_iperf_server_received.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['received'])
+                ping_iperf_server_median.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['median'])
+        except KeyError:
+            pass
+
+        # Add ping management_server latency results if available
+        try:
+            if edge['speedtest']['ping']['management_server']['avg']:
+                ping_management_server_min.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['min'])
+                ping_management_server_avg.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['avg'])
+                ping_management_server_max.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['max'])
+                ping_management_server_stddev.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['stddev'])
+                ping_management_server_transmitted.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['transmitted'])
+                ping_management_server_received.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['received'])
+                ping_management_server_median.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['median'])
         except KeyError:
             pass
 
@@ -376,14 +536,39 @@
 
     res.append(prom.generate_latest(cp_status))
     res.append(prom.generate_latest(up_status))
+
+    res.append(prom.generate_latest(ping_dry_run_min))
+    res.append(prom.generate_latest(ping_dry_run_avg))
+    res.append(prom.generate_latest(ping_dry_run_max))
+    res.append(prom.generate_latest(ping_dry_run_stddev))
+    res.append(prom.generate_latest(ping_dry_run_transmitted))
+    res.append(prom.generate_latest(ping_dry_run_received))
+    res.append(prom.generate_latest(ping_dry_run_median))
+
     res.append(prom.generate_latest(ping_dns_min))
     res.append(prom.generate_latest(ping_dns_avg))
     res.append(prom.generate_latest(ping_dns_max))
     res.append(prom.generate_latest(ping_dns_stddev))
+    res.append(prom.generate_latest(ping_dns_transmitted))
+    res.append(prom.generate_latest(ping_dns_received))
+    res.append(prom.generate_latest(ping_dns_median))
+
     res.append(prom.generate_latest(ping_iperf_server_min))
     res.append(prom.generate_latest(ping_iperf_server_avg))
     res.append(prom.generate_latest(ping_iperf_server_max))
     res.append(prom.generate_latest(ping_iperf_server_stddev))
+    res.append(prom.generate_latest(ping_iperf_server_transmitted))
+    res.append(prom.generate_latest(ping_iperf_server_received))
+    res.append(prom.generate_latest(ping_iperf_server_median))
+
+    res.append(prom.generate_latest(ping_management_server_min))
+    res.append(prom.generate_latest(ping_management_server_avg))
+    res.append(prom.generate_latest(ping_management_server_max))
+    res.append(prom.generate_latest(ping_management_server_stddev))
+    res.append(prom.generate_latest(ping_management_server_transmitted))
+    res.append(prom.generate_latest(ping_management_server_received))
+    res.append(prom.generate_latest(ping_management_server_median))
+
     res.append(prom.generate_latest(iperf_cluster_downlink))
     res.append(prom.generate_latest(iperf_cluster_uplink))
     res.append(prom.generate_latest(last_update))
@@ -435,13 +620,37 @@
         },
         'speedtest': {
             'ping': {
+                'dry_run': {
+                    'transmitted' : 0,
+                    'received' : 0,
+                    'median' : 0.0,
+                    'min': 0.0,
+                    'avg': 0.0,
+                    'max': 0.0,
+                    'stddev': 0.0
+                },
                 'dns': {
+                    'transmitted' : 0,
+                    'received' : 0,
+                    'median' : 0.0,
                     'min': 0.0,
                     'avg': 0.0,
                     'max': 0.0,
                     'stddev': 0.0
                 },
                 'iperf_server': {
+                    'transmitted' : 0,
+                    'received' : 0,
+                    'median' : 0.0,
+                    'min': 0.0,
+                    'avg': 0.0,
+                    'max': 0.0,
+                    'stddev': 0.0
+                },
+                'management_server': {
+                    'transmitted' : 0,
+                    'received' : 0,
+                    'median' : 0.0,
                     'min': 0.0,
                     'avg': 0.0,
                     'max': 0.0,
diff --git a/edge-monitoring-server/test_edge_monitoring_server.py b/edge-monitoring-server/test_edge_monitoring_server.py
index 24b8953..146bfca 100755
--- a/edge-monitoring-server/test_edge_monitoring_server.py
+++ b/edge-monitoring-server/test_edge_monitoring_server.py
@@ -21,17 +21,41 @@
     },
     'speedtest': {
         'ping': {
+            'dry_run': {
+                'transmitted': 3,
+                'received': 2,
+                'median': 5.0,
+                'min': 1.0,
+                'avg': 5.0,
+                'max': 9.0,
+                'stddev': 1.0
+            },
             'dns': {
+                'transmitted': 10,
+                'received': 9,
+                'median': 4.0,
                 'min': 2.0,
                 'avg': 4.0,
                 'max': 6.0,
                 'stddev': 1.0
             },
             'iperf_server': {
+                'transmitted': 10,
+                'received': 10,
+                'median': 3.0,
                 'min': 1.0,
                 'avg': 3.0,
                 'max': 5.0,
                 'stddev': 1.0
+            },
+            'management_server': {
+                'transmitted': 10,
+                'received': 8,
+                'median': 6.0,
+                'min': 2.0,
+                'avg': 6.0,
+                'max': 10.0,
+                'stddev': 1.0
             }
         },
         'iperf': {
@@ -78,17 +102,41 @@
     },
     'speedtest': {
         'ping': {
+            'dry_run': {
+                'transmitted': 3,
+                'received': 2,
+                'median': 5.0,
+                'min': 1.0,
+                'avg': 5.0,
+                'max': 9.0,
+                'stddev': 1.0
+            },
             'dns': {
+                'transmitted': 10,
+                'received': 9,
+                'median': 4.0,
                 'min': 2.0,
                 'avg': 4.0,
                 'max': 6.0,
                 'stddev': 1.0
             },
             'iperf_server': {
+                'transmitted': 10,
+                'received': 10,
+                'median': 3.0,
                 'min': 1.0,
                 'avg': 3.0,
                 'max': 5.0,
                 'stddev': 1.0
+            },
+            'management_server': {
+                'transmitted': 10,
+                'received': 8,
+                'median': 6.0,
+                'min': 2.0,
+                'avg': 6.0,
+                'max': 10.0,
+                'stddev': 1.0
             }
         },
         'iperf': {
@@ -124,6 +172,128 @@
     'last_update': time.time()
 }
 
+test_edge_pre_0_7_0 = {
+    'name': 'ace-menlo-rasp-pi',
+    'status': {
+        'control_plane': 'connected',
+        'user_plane': 'connected'
+    },
+    'speedtest': {
+        'ping': {
+            'dns': {
+                'min': 2.0,
+                'avg': 4.0,
+                'max': 6.0,
+                'stddev': 1.0
+            },
+            'iperf_server': {
+                'min': 1.0,
+                'avg': 3.0,
+                'max': 5.0,
+                'stddev': 1.0
+            }
+        },
+        'iperf': {
+            'cluster': {
+                'downlink': 100.0,
+                'uplink': 10.0
+            }
+        }
+    },
+    'signal_quality': {
+        'rsrq': 30,
+        'rsrp': 80
+    },
+    'last_update': time.time()
+}
+
+test_edge_dns_iperf = {
+    'name': 'ace-menlo-rasp-pi',
+    'status': {
+        'control_plane': 'connected',
+        'user_plane': 'connected'
+    },
+    'speedtest': {
+        'ping': {
+            'dns': {
+                'transmitted': 10,
+                'received': 9,
+                'median': 4.0,
+                'min': 2.0,
+                'avg': 4.0,
+                'max': 6.0,
+                'stddev': 1.0
+            },
+            'iperf_server': {
+                'transmitted': 10,
+                'received': 10,
+                'median': 3.0,
+                'min': 1.0,
+                'avg': 3.0,
+                'max': 5.0,
+                'stddev': 1.0
+            }
+        },
+        'iperf': {
+            'cluster': {
+                'downlink': 100.0,
+                'uplink': 10.0
+            }
+        }
+    },
+    'signal_quality': {
+        'rsrq': 30,
+        'rsrp': 80
+    },
+    'last_update': time.time()
+}
+
+test_edge_basic_ping_stats = {
+    'name': 'ace-menlo-rasp-pi',
+    'status': {
+        'control_plane': 'connected',
+        'user_plane': 'connected'
+    },
+    'speedtest': {
+        'ping': {
+            'dry_run': {
+                'min': 1.0,
+                'avg': 5.0,
+                'max': 9.0,
+                'stddev': 1.0
+            },
+            'dns': {
+                'min': 2.0,
+                'avg': 4.0,
+                'max': 6.0,
+                'stddev': 1.0
+            },
+            'iperf_server': {
+                'min': 1.0,
+                'avg': 3.0,
+                'max': 5.0,
+                'stddev': 1.0
+            },
+            'management_server': {
+                'min': 2.0,
+                'avg': 6.0,
+                'max': 10.0,
+                'stddev': 1.0
+            }
+        },
+        'iperf': {
+            'cluster': {
+                'downlink': 100.0,
+                'uplink': 10.0
+            }
+        }
+    },
+    'signal_quality': {
+        'rsrq': 30,
+        'rsrp': 80
+    },
+    'last_update': time.time()
+}
 
 class MyEvent:
     def __init__ (self, location = "", description = "", summary = "", start = None, end = None, all_day = False):
@@ -163,14 +333,38 @@
         self.assertTrue('aetheredge_e2e_tests_down{name="ace-menlo-rasp-pi"} 0.0' in data)
 
     def _assert_speedtest_metrics_exist(self, data):
+        self.assertTrue('aetheredge_ping_dry_run_test_transmitted{name="ace-menlo-rasp-pi"} 3' in data)
+        self.assertTrue('aetheredge_ping_dry_run_test_received{name="ace-menlo-rasp-pi"} 2' in data)
+        self.assertTrue('aetheredge_ping_dry_run_test_median{name="ace-menlo-rasp-pi"} 5.0' in data)
+        self.assertTrue('aetheredge_ping_dry_run_test_min{name="ace-menlo-rasp-pi"} 1.0' in data)
+        self.assertTrue('aetheredge_ping_dry_run_test_avg{name="ace-menlo-rasp-pi"} 5.0' in data)
+        self.assertTrue('aetheredge_ping_dry_run_test_max{name="ace-menlo-rasp-pi"} 9.0' in data)
+        self.assertTrue('aetheredge_ping_dry_run_test_stddev{name="ace-menlo-rasp-pi"} 1.0' in data)
+
+        self.assertTrue('aetheredge_ping_dns_test_transmitted{name="ace-menlo-rasp-pi"} 10' in data)
+        self.assertTrue('aetheredge_ping_dns_test_received{name="ace-menlo-rasp-pi"} 9' in data)
+        self.assertTrue('aetheredge_ping_dns_test_median{name="ace-menlo-rasp-pi"} 4.0' in data)
         self.assertTrue('aetheredge_ping_dns_test_min{name="ace-menlo-rasp-pi"} 2.0' in data)
         self.assertTrue('aetheredge_ping_dns_test_avg{name="ace-menlo-rasp-pi"} 4.0' in data)
         self.assertTrue('aetheredge_ping_dns_test_max{name="ace-menlo-rasp-pi"} 6.0' in data)
         self.assertTrue('aetheredge_ping_dns_test_stddev{name="ace-menlo-rasp-pi"} 1.0' in data)
+
+        self.assertTrue('aetheredge_ping_iperf_server_test_transmitted{name="ace-menlo-rasp-pi"} 10' in data)
+        self.assertTrue('aetheredge_ping_iperf_server_test_received{name="ace-menlo-rasp-pi"} 10' in data)
+        self.assertTrue('aetheredge_ping_iperf_server_test_median{name="ace-menlo-rasp-pi"} 3.0' in data)
         self.assertTrue('aetheredge_ping_iperf_server_test_min{name="ace-menlo-rasp-pi"} 1.0' in data)
         self.assertTrue('aetheredge_ping_iperf_server_test_avg{name="ace-menlo-rasp-pi"} 3.0' in data)
         self.assertTrue('aetheredge_ping_iperf_server_test_max{name="ace-menlo-rasp-pi"} 5.0' in data)
         self.assertTrue('aetheredge_ping_iperf_server_test_stddev{name="ace-menlo-rasp-pi"} 1.0' in data)
+
+        self.assertTrue('aetheredge_ping_management_server_test_transmitted{name="ace-menlo-rasp-pi"} 10' in data)
+        self.assertTrue('aetheredge_ping_management_server_test_received{name="ace-menlo-rasp-pi"} 8' in data)
+        self.assertTrue('aetheredge_ping_management_server_test_median{name="ace-menlo-rasp-pi"} 6.0' in data)
+        self.assertTrue('aetheredge_ping_management_server_test_min{name="ace-menlo-rasp-pi"} 2.0' in data)
+        self.assertTrue('aetheredge_ping_management_server_test_avg{name="ace-menlo-rasp-pi"} 6.0' in data)
+        self.assertTrue('aetheredge_ping_management_server_test_max{name="ace-menlo-rasp-pi"} 10.0' in data)
+        self.assertTrue('aetheredge_ping_management_server_test_stddev{name="ace-menlo-rasp-pi"} 1.0' in data)
+
         self.assertTrue('aetheredge_iperf_cluster_downlink_test{name="ace-menlo-rasp-pi"} 100.0' in data)
         self.assertTrue('aetheredge_iperf_cluster_uplink_test{name="ace-menlo-rasp-pi"} 10.0' in data)
 
@@ -351,14 +545,38 @@
         data = response.get_data(as_text=True)
         # print(data)
 
+        self.assertFalse('aetheredge_ping_dry_run_test_transmitted{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_dry_run_test_received{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_dry_run_test_median{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_dry_run_test_min{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_dry_run_test_avg{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_dry_run_test_max{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_dry_run_test_stddev{name="ace-menlo-rasp-pi"}' in data)
+
+        self.assertFalse('aetheredge_ping_dns_test_transmitted{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_dns_test_received{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_dns_test_median{name="ace-menlo-rasp-pi"}' in data)
         self.assertFalse('aetheredge_ping_dns_test_min{name="ace-menlo-rasp-pi"}' in data)
         self.assertFalse('aetheredge_ping_dns_test_avg{name="ace-menlo-rasp-pi"}' in data)
         self.assertFalse('aetheredge_ping_dns_test_max{name="ace-menlo-rasp-pi"}' in data)
         self.assertFalse('aetheredge_ping_dns_test_stddev{name="ace-menlo-rasp-pi"}' in data)
+
+        self.assertFalse('aetheredge_ping_iperf_server_test_transmitted{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_iperf_server_test_received{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_iperf_server_test_median{name="ace-menlo-rasp-pi"}' in data)
         self.assertFalse('aetheredge_ping_iperf_server_test_min{name="ace-menlo-rasp-pi"}' in data)
         self.assertFalse('aetheredge_ping_iperf_server_test_avg{name="ace-menlo-rasp-pi"}' in data)
         self.assertFalse('aetheredge_ping_iperf_server_test_max{name="ace-menlo-rasp-pi"}' in data)
         self.assertFalse('aetheredge_ping_iperf_server_test_stddev{name="ace-menlo-rasp-pi"}' in data)
+
+        self.assertFalse('aetheredge_ping_management_server_test_transmitted{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_management_server_test_received{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_management_server_test_median{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_management_server_test_min{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_management_server_test_avg{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_management_server_test_max{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_management_server_test_stddev{name="ace-menlo-rasp-pi"}' in data)
+
         self.assertFalse('aetheredge_iperf_cluster_downlink_test{name="ace-menlo-rasp-pi"}' in data)
         self.assertFalse('aetheredge_iperf_cluster_uplink_test{name="ace-menlo-rasp-pi"}' in data)
 
@@ -422,6 +640,9 @@
 
         self.assertFalse('aetheredge_iperf_cluster_downlink{name="ace-menlo-rasp-pi"}' in data)
         self.assertFalse('aetheredge_iperf_cluster_uplink{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_iperf_server_test_transmitted{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_iperf_server_test_received{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_iperf_server_test_median{name="ace-menlo-rasp-pi"}' in data)
         self.assertFalse('aetheredge_ping_iperf_server_test_min{name="ace-menlo-rasp-pi"}' in data)
         self.assertFalse('aetheredge_ping_iperf_server_test_avg{name="ace-menlo-rasp-pi"}' in data)
         self.assertFalse('aetheredge_ping_iperf_server_test_max{name="ace-menlo-rasp-pi"}' in data)
@@ -431,6 +652,43 @@
         data = json.loads(response.get_data(as_text=True))
         self.assertEqual(data['result'], True)
 
+    def test_backwards_compatible_pre_0_7_0(self):
+        response = self.app.post('/testresults', json=test_edge_pre_0_7_0)
+        data = json.loads(response.get_data(as_text=True))
+        self.assertEqual(data['edge']['name'], 'ace-menlo-rasp-pi')
+
+        response = self.app.get('/edges/metrics')
+        data = response.get_data(as_text=True)
+        # print(data)
+
+        self.assertFalse('aetheredge_ping_dry_run_test_transmitted{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_dry_run_test_received{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_dry_run_test_median{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_dry_run_test_min{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_dry_run_test_avg{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_dry_run_test_max{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_dry_run_test_stddev{name="ace-menlo-rasp-pi"}' in data)
+
+        self.assertFalse('aetheredge_ping_management_server_test_transmitted{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_management_server_test_received{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_management_server_test_median{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_management_server_test_min{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_management_server_test_avg{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_management_server_test_max{name="ace-menlo-rasp-pi"}' in data)
+        self.assertFalse('aetheredge_ping_management_server_test_stddev{name="ace-menlo-rasp-pi"}' in data)
+
+        self.assertFalse('aetheredge_ping_dns_test_transmitted{name="ace-menlo-rasp-pi"} 10' in data)
+        self.assertFalse('aetheredge_ping_dns_test_received{name="ace-menlo-rasp-pi"} 9' in data)
+        self.assertFalse('aetheredge_ping_dns_test_median{name="ace-menlo-rasp-pi"} 4.0' in data)
+
+        self.assertFalse('aetheredge_ping_iperf_server_test_transmitted{name="ace-menlo-rasp-pi"} 10' in data)
+        self.assertFalse('aetheredge_ping_iperf_server_test_received{name="ace-menlo-rasp-pi"} 10' in data)
+        self.assertFalse('aetheredge_ping_iperf_server_test_median{name="ace-menlo-rasp-pi"} 3.0' in data)
+
+        response = self.app.delete('/testresults/ace-menlo-rasp-pi')
+        data = json.loads(response.get_data(as_text=True))
+        self.assertEqual(data['result'], True)
+
     def test_handle_invalid_schema(self):
         response = self.app.post('/testresults', json="")
         self.assertEqual(response.status_code, 400)
diff --git a/edge-monitoring/agent_modem/config.json b/edge-monitoring/agent_modem/config.json
index a824f91..0696c8c 100644
--- a/edge-monitoring/agent_modem/config.json
+++ b/edge-monitoring/agent_modem/config.json
@@ -6,8 +6,10 @@
         "ip_addr": "192.168.0.1"
     },
     "ips": {
-      "dns": "8.8.8.8",
-      "iperf_server": ""
+      "dry_run": "1.1.1.1",
+      "dns": "1.1.1.1",
+      "iperf_server": "",
+      "management_server": ""
     },
     "attach_timeout": 30,
     "detach_timeout": 10,
diff --git a/edge-monitoring/agent_modem/edge_monitoring_agent_modem.py b/edge-monitoring/agent_modem/edge_monitoring_agent_modem.py
index 20678ca..f4b6225 100755
--- a/edge-monitoring/agent_modem/edge_monitoring_agent_modem.py
+++ b/edge-monitoring/agent_modem/edge_monitoring_agent_modem.py
@@ -14,6 +14,7 @@
 import serial
 import subprocess
 from collections import namedtuple
+from statistics import median
 
 '''
 "Simple" script that checks Aether network operational status periodically
@@ -181,23 +182,46 @@
     '''
     Runs the ping test
     Input: IP to ping, # times to ping
-    Returns: dict of the min/avg/max/stddev numbers from the ping command result
+    Returns: Transmitted packets
+             Received packets
+             Median ping ms
+             Min ping ms
+             Avg ping ms
+             Max ping ms
+             Std Dev ping ms
     '''
-    result = {'min': 0.0,
+    result = {'transmitted': 0,
+              'received': 0,
+              'median': 0.0,
+              'min': 0.0,
               'avg': 0.0,
               'max': 0.0,
               'stddev': 0.0}
     if not ip:
         return result, True
     try:
-        pingResult = subprocess.check_output(
-                "ping -c " + str(count) + " " + ip + \
-                " | tail -1 | awk '{print $4}'",
-                shell=True).decode("UTF-8").split("/")
-        result = {'min': float(pingResult[0]),
-                  'avg': float(pingResult[1]),
-                  'max': float(pingResult[2]),
-                  'stddev': float(pingResult[3])}
+        pingOutput = subprocess.check_output(
+                    "ping -c " + str(count) + " " + \
+                    ip, shell=True).decode("UTF-8").split()
+        result['transmitted'] = int(pingOutput[-15])
+        result['received'] = int(pingOutput[-12])
+        if result['received'] > 0:
+            pingValues = []
+
+            # Hack for getting all ping values for median
+            for word in pingOutput:
+                if "time=" in word:
+                    pingValues.append(float(word.split("=")[1]))
+            result['median'] = round(median(pingValues), 3)
+
+            pingResult = pingOutput[-2].split('/')
+            result['min'] = float(pingResult[0])
+            result['avg'] = float(pingResult[1])
+            result['max'] = float(pingResult[2])
+            result['stddev'] = float(pingResult[3])
+        else:
+            logging.error("No packets received during ping " + ip)
+            return result, False
     except Exception as e:
         logging.error("Ping test failed for " + ip + ": %s", e)
         return result, False
@@ -207,16 +231,16 @@
 def get_ping_test(modem):
     '''
     Prepares the ping test.
-    Each ping test result saves the min/avg/max/stddev to dict.
-    1) Performs ping test to Google Public DNS for 10 iterations.
-    2) # TODO: Performs ping to device on network.
+    Runs ping tests from 'ips' entry in config.json in order.
+    Note: 'dry_run' IP entry runs 3 ping iterations. Other IPs run 10 iterations.
     '''
     speedtest_ping = {}
     status = True
     ping_test_passed = True
 
     for i in range(0, len(CONF.ips)):
-        speedtest_ping[CONF.ips._fields[i]], status = run_ping_test(CONF.ips[i], 10)
+        count = 10 if CONF.ips._fields[i] != "dry_run" else 3
+        speedtest_ping[CONF.ips._fields[i]], status = run_ping_test(CONF.ips[i], count)
         if not status:
             ping_test_passed = False
             logging.error("Ping test failed. Not running further tests.")
@@ -297,12 +321,9 @@
         'speedtest': {
             'ping': {
                 'dns': {
-                    'min': 0.0,
-                    'avg': 0.0,
-                    'max': 0.0,
-                    'stddev': 0.0
-                },
-                'iperf_server': {
+                    'transmitted' : 0,
+                    'received' : 0,
+                    'median' : 0.0,
                     'min': 0.0,
                     'avg': 0.0,
                     'max': 0.0,