Commit Diff


commit - 7cb145ba970416743d12a36bb0a4df59264203da
commit + f5fde32e94d77a44e85a28f9263531b34fdf7c8b
blob - 466257ef50678e8aa174715dd15478a37feebd86
blob + e3079723d7c1f155cf738d17b1ff46eaa4a0ecd5
--- service.go
+++ service.go
@@ -12,13 +12,19 @@ func (s Service) path() string {
 
 // Service represents a Service object.
 type Service struct {
-	Name         string `json:"__name"`
-	Groups       []string
-	State        ServiceState
-	CheckCommand string `json:"check_command"`
-	DisplayName  string `json:"display_name:"`
+	Name            string `json:"__name"`
+	Groups          []string
+	State           ServiceState
+	StateType       StateType   `json:"state_type"`
+	CheckCommand    string      `json:"check_command"`
+	DisplayName     string      `json:"display_name"`
+	LastCheckResult CheckResult `json:"last_check_result"`
 }
 
+type CheckResult struct {
+	Output string
+}
+
 type ServiceState int
 
 const (
blob - /dev/null
blob + fa62efe00c98afac76920d3208dfd01dbab87f03 (mode 644)
--- /dev/null
+++ testdata/services.json
@@ -0,0 +1,750 @@
+{
+    "results": [
+        {
+            "attrs": {
+                "__name": "9p.io!http_test",
+                "acknowledgement": 0,
+                "acknowledgement_expiry": 0,
+                "acknowledgement_last_change": 0,
+                "action_url": "",
+                "active": true,
+                "check_attempt": 1,
+                "check_command": "http",
+                "check_interval": 300,
+                "check_period": "",
+                "check_timeout": null,
+                "command_endpoint": "",
+                "display_name": "Plan 9 Mirror site",
+                "downtime_depth": 0,
+                "enable_active_checks": true,
+                "enable_event_handler": true,
+                "enable_flapping": false,
+                "enable_notifications": true,
+                "enable_passive_checks": true,
+                "enable_perfdata": true,
+                "event_command": "",
+                "executions": null,
+                "flapping": false,
+                "flapping_current": 21.4,
+                "flapping_ignore_states": null,
+                "flapping_last_change": 1642495293.180023,
+                "flapping_threshold": 0,
+                "flapping_threshold_high": 30,
+                "flapping_threshold_low": 25,
+                "force_next_check": false,
+                "force_next_notification": false,
+                "groups": [],
+                "ha_mode": 0,
+                "handled": true,
+                "host_name": "9p.io",
+                "icon_image": "",
+                "icon_image_alt": "",
+                "last_check": 1642495293.180141,
+                "last_check_result": {
+                    "active": true,
+                    "check_source": "alpine.olowe.co",
+                    "command": [
+                        "/usr/lib/monitoring-plugins/check_http",
+                        "-I",
+                        "9p.io"
+                    ],
+                    "execution_end": 1642495293.180023,
+                    "execution_start": 1642495292.485154,
+                    "exit_status": 0,
+                    "output": "HTTP OK: HTTP/1.1 200 OK - 1714 bytes in 0.693 second response time ",
+                    "performance_data": [
+                        "time=0.692599s;;;0.000000;10.000000",
+                        "size=1714B;;;0"
+                    ],
+                    "schedule_end": 1642495293.180141,
+                    "schedule_start": 1642495292.48,
+                    "scheduling_source": "alpine.olowe.co",
+                    "state": 0,
+                    "ttl": 0,
+                    "type": "CheckResult",
+                    "vars_after": {
+                        "attempt": 1,
+                        "reachable": false,
+                        "state": 0,
+                        "state_type": 1
+                    },
+                    "vars_before": {
+                        "attempt": 1,
+                        "reachable": false,
+                        "state": 0,
+                        "state_type": 1
+                    }
+                },
+                "last_hard_state": 0,
+                "last_hard_state_change": 1642491111.2022,
+                "last_reachable": false,
+                "last_state": 0,
+                "last_state_change": 1642491111.2022,
+                "last_state_critical": 1642491042.398463,
+                "last_state_ok": 1642495293.180023,
+                "last_state_type": 1,
+                "last_state_unknown": 0,
+                "last_state_unreachable": 1642495293.180023,
+                "last_state_warning": 0,
+                "max_check_attempts": 3,
+                "name": "http_test",
+                "next_check": 1642495583.510205,
+                "next_update": 1642495884.910251,
+                "notes": "",
+                "notes_url": "",
+                "original_attributes": null,
+                "package": "_api",
+                "paused": false,
+                "previous_state_change": 1642491111.2022,
+                "problem": false,
+                "retry_interval": 60,
+                "severity": 0,
+                "source_location": {
+                    "first_column": 0,
+                    "first_line": 1,
+                    "last_column": 25,
+                    "last_line": 1,
+                    "path": "/var/lib/icinga2/api/packages/_api/19602f4d-849c-4589-a9fe-cc1c71790f3c/conf.d/services/9p.io!http_test.conf"
+                },
+                "state": 0,
+                "state_type": 1,
+                "templates": [
+                    "http_test"
+                ],
+                "type": "Service",
+                "vars": null,
+                "version": 1641624438.058955,
+                "volatile": false,
+                "zone": "alpine.olowe.co"
+            },
+            "joins": {},
+            "meta": {},
+            "name": "9p.io!http_test",
+            "type": "Service"
+        },
+        {
+            "attrs": {
+                "__name": "google.com!ping",
+                "acknowledgement": 0,
+                "acknowledgement_expiry": 0,
+                "acknowledgement_last_change": 0,
+                "action_url": "",
+                "active": true,
+                "check_attempt": 1,
+                "check_command": "ping",
+                "check_interval": 60,
+                "check_period": "",
+                "check_timeout": null,
+                "command_endpoint": "",
+                "display_name": "ping",
+                "downtime_depth": 0,
+                "enable_active_checks": true,
+                "enable_event_handler": true,
+                "enable_flapping": false,
+                "enable_notifications": true,
+                "enable_passive_checks": true,
+                "enable_perfdata": true,
+                "event_command": "",
+                "executions": null,
+                "flapping": false,
+                "flapping_current": 0,
+                "flapping_ignore_states": null,
+                "flapping_last_change": 1642484989.400779,
+                "flapping_threshold": 0,
+                "flapping_threshold_high": 30,
+                "flapping_threshold_low": 25,
+                "force_next_check": false,
+                "force_next_notification": false,
+                "groups": [],
+                "ha_mode": 0,
+                "handled": true,
+                "host_name": "google.com",
+                "icon_image": "",
+                "icon_image_alt": "",
+                "last_check": 1642495247.470693,
+                "last_check_result": {
+                    "active": true,
+                    "check_source": "alpine.olowe.co",
+                    "command": [
+                        "/usr/lib/monitoring-plugins/check_ping",
+                        "-H",
+                        "google.com",
+                        "-c",
+                        "200,15%",
+                        "-w",
+                        "100,5%"
+                    ],
+                    "execution_end": 1642495247.470578,
+                    "execution_start": 1642495236.419897,
+                    "exit_status": 2,
+                    "output": "CRITICAL - Plugin timed out after 10 seconds",
+                    "performance_data": [],
+                    "schedule_end": 1642495247.470693,
+                    "schedule_start": 1642495236.413627,
+                    "scheduling_source": "alpine.olowe.co",
+                    "state": 2,
+                    "ttl": 0,
+                    "type": "CheckResult",
+                    "vars_after": {
+                        "attempt": 1,
+                        "reachable": false,
+                        "state": 2,
+                        "state_type": 1
+                    },
+                    "vars_before": {
+                        "attempt": 1,
+                        "reachable": false,
+                        "state": 2,
+                        "state_type": 1
+                    }
+                },
+                "last_hard_state": 2,
+                "last_hard_state_change": 1642492967.825117,
+                "last_reachable": false,
+                "last_state": 2,
+                "last_state_change": 1642492967.825117,
+                "last_state_critical": 1642495247.470578,
+                "last_state_ok": 0,
+                "last_state_type": 1,
+                "last_state_unknown": 1642492879.078709,
+                "last_state_unreachable": 1642495247.470578,
+                "last_state_warning": 0,
+                "max_check_attempts": 5,
+                "name": "ping",
+                "next_check": 1642495365.432228,
+                "next_update": 1642495447.5461302,
+                "notes": "",
+                "notes_url": "",
+                "original_attributes": null,
+                "package": "_etc",
+                "paused": false,
+                "previous_state_change": 1642492967.825117,
+                "problem": true,
+                "retry_interval": 30,
+                "severity": 1152,
+                "source_location": {
+                    "first_column": 1,
+                    "first_line": 49,
+                    "last_column": 20,
+                    "last_line": 49,
+                    "path": "/etc/icinga2/conf.d/ye.conf"
+                },
+                "state": 2,
+                "state_type": 1,
+                "templates": [
+                    "ping",
+                    "generic-service"
+                ],
+                "type": "Service",
+                "vars": null,
+                "version": 0,
+                "volatile": false,
+                "zone": ""
+            },
+            "joins": {},
+            "meta": {},
+            "name": "google.com!ping",
+            "type": "Service"
+        },
+        {
+            "attrs": {
+                "__name": "9p.io!ping",
+                "acknowledgement": 0,
+                "acknowledgement_expiry": 0,
+                "acknowledgement_last_change": 0,
+                "action_url": "",
+                "active": true,
+                "check_attempt": 1,
+                "check_command": "ping",
+                "check_interval": 60,
+                "check_period": "",
+                "check_timeout": null,
+                "command_endpoint": "",
+                "display_name": "ping",
+                "downtime_depth": 0,
+                "enable_active_checks": true,
+                "enable_event_handler": true,
+                "enable_flapping": false,
+                "enable_notifications": true,
+                "enable_passive_checks": true,
+                "enable_perfdata": true,
+                "event_command": "",
+                "executions": null,
+                "flapping": false,
+                "flapping_current": 0,
+                "flapping_ignore_states": null,
+                "flapping_last_change": 1642485044.430574,
+                "flapping_threshold": 0,
+                "flapping_threshold_high": 30,
+                "flapping_threshold_low": 25,
+                "force_next_check": false,
+                "force_next_notification": false,
+                "groups": [],
+                "ha_mode": 0,
+                "handled": true,
+                "host_name": "9p.io",
+                "icon_image": "",
+                "icon_image_alt": "",
+                "last_check": 1642495312.470173,
+                "last_check_result": {
+                    "active": true,
+                    "check_source": "alpine.olowe.co",
+                    "command": [
+                        "/usr/lib/monitoring-plugins/check_ping",
+                        "-H",
+                        "9p.io",
+                        "-c",
+                        "200,15%",
+                        "-w",
+                        "100,5%"
+                    ],
+                    "execution_end": 1642495312.470065,
+                    "execution_start": 1642495302.422573,
+                    "exit_status": 2,
+                    "output": "PING CRITICAL - Packet loss = 100%",
+                    "performance_data": [
+                        "rta=200.000000ms;100.000000;200.000000;0.000000",
+                        "pl=100%;5;15;0"
+                    ],
+                    "schedule_end": 1642495312.470173,
+                    "schedule_start": 1642495302.4164212,
+                    "scheduling_source": "alpine.olowe.co",
+                    "state": 2,
+                    "ttl": 0,
+                    "type": "CheckResult",
+                    "vars_after": {
+                        "attempt": 1,
+                        "reachable": false,
+                        "state": 2,
+                        "state_type": 1
+                    },
+                    "vars_before": {
+                        "attempt": 1,
+                        "reachable": false,
+                        "state": 2,
+                        "state_type": 1
+                    }
+                },
+                "last_hard_state": 2,
+                "last_hard_state_change": 1642492628.221177,
+                "last_reachable": false,
+                "last_state": 2,
+                "last_state_change": 1642492628.221177,
+                "last_state_critical": 1642495312.470065,
+                "last_state_ok": 0,
+                "last_state_type": 1,
+                "last_state_unknown": 1642492530.853331,
+                "last_state_unreachable": 1642495312.470065,
+                "last_state_warning": 0,
+                "max_check_attempts": 5,
+                "name": "ping",
+                "next_check": 1642495370.410216,
+                "next_update": 1642495450.517504,
+                "notes": "",
+                "notes_url": "",
+                "original_attributes": null,
+                "package": "_etc",
+                "paused": false,
+                "previous_state_change": 1642492628.221177,
+                "problem": true,
+                "retry_interval": 30,
+                "severity": 1152,
+                "source_location": {
+                    "first_column": 1,
+                    "first_line": 49,
+                    "last_column": 20,
+                    "last_line": 49,
+                    "path": "/etc/icinga2/conf.d/ye.conf"
+                },
+                "state": 2,
+                "state_type": 1,
+                "templates": [
+                    "ping",
+                    "generic-service"
+                ],
+                "type": "Service",
+                "vars": null,
+                "version": 0,
+                "volatile": false,
+                "zone": ""
+            },
+            "joins": {},
+            "meta": {},
+            "name": "9p.io!ping",
+            "type": "Service"
+        },
+        {
+            "attrs": {
+                "__name": "google.com!http",
+                "acknowledgement": 0,
+                "acknowledgement_expiry": 0,
+                "acknowledgement_last_change": 0,
+                "action_url": "",
+                "active": true,
+                "check_attempt": 1,
+                "check_command": "http",
+                "check_interval": 60,
+                "check_period": "",
+                "check_timeout": null,
+                "command_endpoint": "",
+                "display_name": "http",
+                "downtime_depth": 0,
+                "enable_active_checks": true,
+                "enable_event_handler": true,
+                "enable_flapping": false,
+                "enable_notifications": true,
+                "enable_passive_checks": true,
+                "enable_perfdata": true,
+                "event_command": "",
+                "executions": null,
+                "flapping": true,
+                "flapping_current": 61.30000000000001,
+                "flapping_ignore_states": null,
+                "flapping_last_change": 1642473965.500139,
+                "flapping_threshold": 0,
+                "flapping_threshold_high": 30,
+                "flapping_threshold_low": 25,
+                "force_next_check": false,
+                "force_next_notification": false,
+                "groups": [],
+                "ha_mode": 0,
+                "handled": true,
+                "host_name": "google.com",
+                "icon_image": "",
+                "icon_image_alt": "",
+                "last_check": 1642495295.533075,
+                "last_check_result": {
+                    "active": true,
+                    "check_source": "alpine.olowe.co",
+                    "command": [
+                        "/usr/lib/monitoring-plugins/check_http",
+                        "-I",
+                        "google.com"
+                    ],
+                    "execution_end": 1642495295.532951,
+                    "execution_start": 1642495295.198121,
+                    "exit_status": 0,
+                    "output": "HTTP OK: HTTP/1.0 200 OK - 14741 bytes in 0.333 second response time ",
+                    "performance_data": [
+                        "time=0.332556s;;;0.000000;10.000000",
+                        "size=14741B;;;0"
+                    ],
+                    "schedule_end": 1642495295.533075,
+                    "schedule_start": 1642495295.194311,
+                    "scheduling_source": "alpine.olowe.co",
+                    "state": 0,
+                    "ttl": 0,
+                    "type": "CheckResult",
+                    "vars_after": {
+                        "attempt": 1,
+                        "reachable": false,
+                        "state": 0,
+                        "state_type": 1
+                    },
+                    "vars_before": {
+                        "attempt": 1,
+                        "reachable": false,
+                        "state": 0,
+                        "state_type": 1
+                    }
+                },
+                "last_hard_state": 0,
+                "last_hard_state_change": 1642495062.249295,
+                "last_reachable": false,
+                "last_state": 0,
+                "last_state_change": 1642495062.249295,
+                "last_state_critical": 1642494666.56194,
+                "last_state_ok": 1642495295.532951,
+                "last_state_type": 1,
+                "last_state_unknown": 1642495040.576216,
+                "last_state_unreachable": 1642495295.532951,
+                "last_state_warning": 1642494954.127325,
+                "max_check_attempts": 5,
+                "name": "http",
+                "next_check": 1642495353.563125,
+                "next_update": 1642495414.2404053,
+                "notes": "",
+                "notes_url": "",
+                "original_attributes": null,
+                "package": "_etc",
+                "paused": false,
+                "previous_state_change": 1642495062.249295,
+                "problem": false,
+                "retry_interval": 30,
+                "severity": 0,
+                "source_location": {
+                    "first_column": 1,
+                    "first_line": 55,
+                    "last_column": 20,
+                    "last_line": 55,
+                    "path": "/etc/icinga2/conf.d/ye.conf"
+                },
+                "state": 0,
+                "state_type": 1,
+                "templates": [
+                    "http",
+                    "generic-service"
+                ],
+                "type": "Service",
+                "vars": null,
+                "version": 0,
+                "volatile": false,
+                "zone": ""
+            },
+            "joins": {},
+            "meta": {},
+            "name": "google.com!http",
+            "type": "Service"
+        },
+        {
+            "attrs": {
+                "__name": "alpine.olowe.co!ping",
+                "acknowledgement": 0,
+                "acknowledgement_expiry": 0,
+                "acknowledgement_last_change": 0,
+                "action_url": "",
+                "active": true,
+                "check_attempt": 1,
+                "check_command": "ping",
+                "check_interval": 60,
+                "check_period": "",
+                "check_timeout": null,
+                "command_endpoint": "",
+                "display_name": "ping",
+                "downtime_depth": 0,
+                "enable_active_checks": true,
+                "enable_event_handler": true,
+                "enable_flapping": false,
+                "enable_notifications": true,
+                "enable_passive_checks": true,
+                "enable_perfdata": true,
+                "event_command": "",
+                "executions": null,
+                "flapping": false,
+                "flapping_current": 0,
+                "flapping_ignore_states": null,
+                "flapping_last_change": 1642475734.693114,
+                "flapping_threshold": 0,
+                "flapping_threshold_high": 30,
+                "flapping_threshold_low": 25,
+                "force_next_check": false,
+                "force_next_notification": false,
+                "groups": [],
+                "ha_mode": 0,
+                "handled": false,
+                "host_name": "alpine.olowe.co",
+                "icon_image": "",
+                "icon_image_alt": "",
+                "last_check": 1642495310.635926,
+                "last_check_result": {
+                    "active": true,
+                    "check_source": "alpine.olowe.co",
+                    "command": [
+                        "/usr/lib/monitoring-plugins/check_ping",
+                        "-H",
+                        "127.0.0.1",
+                        "-c",
+                        "200,15%",
+                        "-w",
+                        "100,5%"
+                    ],
+                    "execution_end": 1642495310.635805,
+                    "execution_start": 1642495306.58951,
+                    "exit_status": 0,
+                    "output": "PING OK - Packet loss = 0%, RTA = 0.08 ms",
+                    "performance_data": [
+                        "rta=0.079000ms;100.000000;200.000000;0.000000",
+                        "pl=0%;5;15;0"
+                    ],
+                    "schedule_end": 1642495310.635926,
+                    "schedule_start": 1642495306.584778,
+                    "scheduling_source": "alpine.olowe.co",
+                    "state": 0,
+                    "ttl": 0,
+                    "type": "CheckResult",
+                    "vars_after": {
+                        "attempt": 1,
+                        "reachable": true,
+                        "state": 0,
+                        "state_type": 1
+                    },
+                    "vars_before": {
+                        "attempt": 1,
+                        "reachable": true,
+                        "state": 0,
+                        "state_type": 1
+                    }
+                },
+                "last_hard_state": 0,
+                "last_hard_state_change": 1642493596.265094,
+                "last_reachable": true,
+                "last_state": 0,
+                "last_state_change": 1642493596.265094,
+                "last_state_critical": 1642493534.064059,
+                "last_state_ok": 1642495310.635805,
+                "last_state_type": 1,
+                "last_state_unknown": 0,
+                "last_state_unreachable": 1642493596.265094,
+                "last_state_warning": 0,
+                "max_check_attempts": 5,
+                "name": "ping",
+                "next_check": 1642495368.635974,
+                "next_update": 1642495436.7380276,
+                "notes": "",
+                "notes_url": "",
+                "original_attributes": null,
+                "package": "_etc",
+                "paused": false,
+                "previous_state_change": 1642493596.265094,
+                "problem": false,
+                "retry_interval": 30,
+                "severity": 0,
+                "source_location": {
+                    "first_column": 1,
+                    "first_line": 49,
+                    "last_column": 20,
+                    "last_line": 49,
+                    "path": "/etc/icinga2/conf.d/ye.conf"
+                },
+                "state": 0,
+                "state_type": 1,
+                "templates": [
+                    "ping",
+                    "generic-service"
+                ],
+                "type": "Service",
+                "vars": null,
+                "version": 0,
+                "volatile": false,
+                "zone": ""
+            },
+            "joins": {},
+            "meta": {},
+            "name": "alpine.olowe.co!ping",
+            "type": "Service"
+        },
+        {
+            "attrs": {
+                "__name": "9p.io!http",
+                "acknowledgement": 0,
+                "acknowledgement_expiry": 0,
+                "acknowledgement_last_change": 0,
+                "action_url": "",
+                "active": true,
+                "check_attempt": 1,
+                "check_command": "http",
+                "check_interval": 60,
+                "check_period": "",
+                "check_timeout": null,
+                "command_endpoint": "",
+                "display_name": "http",
+                "downtime_depth": 0,
+                "enable_active_checks": true,
+                "enable_event_handler": true,
+                "enable_flapping": false,
+                "enable_notifications": true,
+                "enable_passive_checks": true,
+                "enable_perfdata": true,
+                "event_command": "",
+                "executions": null,
+                "flapping": false,
+                "flapping_current": 23.3,
+                "flapping_ignore_states": null,
+                "flapping_last_change": 1642495283.418991,
+                "flapping_threshold": 0,
+                "flapping_threshold_high": 30,
+                "flapping_threshold_low": 25,
+                "force_next_check": false,
+                "force_next_notification": false,
+                "groups": [],
+                "ha_mode": 0,
+                "handled": true,
+                "host_name": "9p.io",
+                "icon_image": "",
+                "icon_image_alt": "",
+                "last_check": 1642495283.419103,
+                "last_check_result": {
+                    "active": true,
+                    "check_source": "alpine.olowe.co",
+                    "command": [
+                        "/usr/lib/monitoring-plugins/check_http",
+                        "-I",
+                        "9p.io"
+                    ],
+                    "execution_end": 1642495283.418991,
+                    "execution_start": 1642495282.711638,
+                    "exit_status": 0,
+                    "output": "HTTP OK: HTTP/1.1 200 OK - 1714 bytes in 0.703 second response time ",
+                    "performance_data": [
+                        "time=0.703348s;;;0.000000;10.000000",
+                        "size=1714B;;;0"
+                    ],
+                    "schedule_end": 1642495283.419103,
+                    "schedule_start": 1642495282.709361,
+                    "scheduling_source": "alpine.olowe.co",
+                    "state": 0,
+                    "ttl": 0,
+                    "type": "CheckResult",
+                    "vars_after": {
+                        "attempt": 1,
+                        "reachable": false,
+                        "state": 0,
+                        "state_type": 1
+                    },
+                    "vars_before": {
+                        "attempt": 1,
+                        "reachable": false,
+                        "state": 0,
+                        "state_type": 1
+                    }
+                },
+                "last_hard_state": 0,
+                "last_hard_state_change": 1642494988.994212,
+                "last_reachable": false,
+                "last_state": 0,
+                "last_state_change": 1642494988.994212,
+                "last_state_critical": 1642494810.489733,
+                "last_state_ok": 1642495283.418991,
+                "last_state_type": 1,
+                "last_state_unknown": 1642494869.390854,
+                "last_state_unreachable": 1642495283.418991,
+                "last_state_warning": 1642494987.196548,
+                "max_check_attempts": 5,
+                "name": "http",
+                "next_check": 1642495342.839149,
+                "next_update": 1642495404.258409,
+                "notes": "",
+                "notes_url": "",
+                "original_attributes": null,
+                "package": "_etc",
+                "paused": false,
+                "previous_state_change": 1642494988.994212,
+                "problem": false,
+                "retry_interval": 30,
+                "severity": 0,
+                "source_location": {
+                    "first_column": 1,
+                    "first_line": 55,
+                    "last_column": 20,
+                    "last_line": 55,
+                    "path": "/etc/icinga2/conf.d/ye.conf"
+                },
+                "state": 0,
+                "state_type": 1,
+                "templates": [
+                    "http",
+                    "generic-service"
+                ],
+                "type": "Service",
+                "vars": null,
+                "version": 0,
+                "volatile": false,
+                "zone": ""
+            },
+            "joins": {},
+            "meta": {},
+            "name": "9p.io!http",
+            "type": "Service"
+        }
+    ]
+}
blob - /dev/null
blob + 589b4df48e8ac7c1a0e2bd753a75152e33f1dacd (mode 644)
--- /dev/null
+++ service_test.go
@@ -0,0 +1,65 @@
+package icinga
+
+import (
+	"encoding/json"
+	"os"
+	"reflect"
+	"testing"
+)
+
+func TestServiceUnmarshal(t *testing.T) {
+	f, err := os.Open("testdata/services.json")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer f.Close()
+	resp, err := parseResponse(f)
+	if err != nil {
+		t.Fatal(err)
+	}
+	want := Service{
+		Name:         "9p.io!http",
+		Groups:       []string{},
+		State:        ServiceOK,
+		StateType:    StateHard,
+		CheckCommand: "http",
+		DisplayName:  "http",
+		LastCheckResult: CheckResult{
+			Output: "HTTP OK: HTTP/1.1 200 OK - 1714 bytes in 0.703 second response time ",
+		},
+	}
+	var got Service
+	for _, r := range resp.Results {
+		if r.name() == "9p.io!http" {
+			got = r.(Service)
+		}
+	}
+	if !reflect.DeepEqual(want, got) {
+		t.Fail()
+	}
+	t.Logf("want %+v, got %+v", want, got)
+}
+
+func TestServiceMarshal(t *testing.T) {
+	want := `{"attrs":{"check_command":"http","display_name":"http"}}`
+
+	b, err := json.Marshal(Service{
+		Name:         "9p.io!http",
+		Groups:       []string{},
+		State:        ServiceOK,
+		StateType:    StateHard,
+		CheckCommand: "http",
+		DisplayName:  "http",
+		LastCheckResult: CheckResult{
+			Output: "HTTP OK: HTTP/1.1 200 OK - 1714 bytes in 0.703 second response time ",
+		},
+	})
+	if err != nil {
+		t.Error(err)
+	}
+	got := string(b)
+	if want != got {
+		t.Fail()
+	}
+	t.Log("want", want, "got", got)
+}