[rygel/wip/basic-management: 123/138] core: Add ping command support to BasicManagement
- From: Jussi Kukkonen <jussik src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rygel/wip/basic-management: 123/138] core: Add ping command support to BasicManagement
- Date: Tue, 10 Sep 2013 07:32:01 +0000 (UTC)
commit 00b89595924e06ef9e2ddd9757bac89d06135ead
Author: Christophe Guiraud <christophe guiraud intel com>
Date: Wed Jun 5 14:06:50 2013 +0200
core: Add ping command support to BasicManagement
- Add the ping command support: build and call the system command,
parse its result output.
- Fix a typo in update_test_ids_lists() funtion in file
rygel-basic-management.vala
.../rygel-basic-management-test-ping.vala | 208 ++++++++++++++-----
src/librygel-core/rygel-basic-management.vala | 27 ++--
2 files changed, 167 insertions(+), 68 deletions(-)
---
diff --git a/src/librygel-core/rygel-basic-management-test-ping.vala
b/src/librygel-core/rygel-basic-management-test-ping.vala
index 06b6faa..bd20efb 100644
--- a/src/librygel-core/rygel-basic-management-test-ping.vala
+++ b/src/librygel-core/rygel-basic-management-test-ping.vala
@@ -25,96 +25,194 @@ using GLib;
// Helper class for BasicManagementTestPing.
internal class Rygel.BasicManagementTestPing : BasicManagementTest {
+ private enum ProcessState {
+ INIT,
+ STATISTICS,
+ RTT,
+ }
- private string host;
- private uint repeat_count;
- private uint data_block_size;
- private uint dscp;
- private uint32 interval_time_out;
+ private enum Status {
+ SUCCESS,
+ ERROR_CANNOT_RESOLVE_HOSTNAME,
+ ERROR_INTERNAL,
+ ERROR_OTHER;
+
+ public string to_string() {
+ switch (this) {
+ case SUCCESS:
+ return "Success";
+ case ERROR_CANNOT_RESOLVE_HOSTNAME:
+ return "Error_CannotResolveHostName";
+ case ERROR_INTERNAL:
+ return "Error_Internal";
+ case ERROR_OTHER:
+ return "Error_Other";
+ default:
+ assert_not_reached();
+ }
+ }
+ }
- private string status;
+ private ProcessState state;
+ private Status status;
private string additional_info;
private uint success_count;
private uint failure_count;
- private uint32 average_response_time;
+ private uint32 avg_response_time;
private uint32 min_response_time;
private uint32 max_response_time;
- private static const uint PING_MIN_REPEAT_COUNT = 1;
- private static const uint PING_MAX_REPEAT_COUNT = 100;
- private static const uint PING_DEFAULT_REPEAT_COUNT = 1;
- private static const uint PING_MIN_REQUEST_INTERVAL_TIMEOUT = 1000;
- private static const uint PING_MAX_REQUEST_INTERVAL_TIMEOUT = 30000;
- private static const uint PING_DEFAULT_REQUEST_INTERVAL_TIMEOUT = 10000;
- private static const uint PING_MIN_DATA_BLOCK_SIZE = 20;
- private static const uint PING_MAX_DATA_BLOCK_SIZE = 2048;
- private static const uint PING_DEFAULT_DATA_BLOCK_SIZE = 32;
- private static const uint PING_MIN_DSCP = 1;
- private static const uint PING_MAX_DSCP = 64;
- private static const uint PING_DEFAULT_DSCP = 30;
- private static const uint PING_MAX_ADDITIONAL_INFO_STR_SIZE = 1024;
- private static const uint PING_MAX_STATUS_STR_SIZE = 32;
- private static const uint PING_MAX_RESULT_ARRAY_SIZE = 7;
+ private static const uint MIN_REPEAT_COUNT = 1;
+ private static const uint MAX_REPEAT_COUNT = 100;
+ private static const uint DEFAULT_REPEAT_COUNT = 1;
+ private static const uint DEFAULT_REPLY_TIMEOUT = 10000;
+ private static const uint MIN_REQUEST_INTERVAL_TIMEOUT = 1000;
+ private static const uint MAX_REQUEST_INTERVAL_TIMEOUT = 30000;
+ private static const uint DEFAULT_REQUEST_INTERVAL_TIMEOUT = 10000;
+ private static const uint MIN_DATA_BLOCK_SIZE = 20;
+ private static const uint MAX_DATA_BLOCK_SIZE = 2048;
+ private static const uint DEFAULT_DATA_BLOCK_SIZE = 32;
+ private static const uint MIN_DSCP = 1;
+ private static const uint MAX_DSCP = 64;
+ private static const uint DEFAULT_DSCP = 30;
public override string method_type { get { return "Ping"; } }
public override string results_type { get { return "GetPingResult"; } }
- public bool init(string host, uint repeat_count, uint data_block_size,
- uint dscp, uint32 interval_time_out) {
- stdout.printf("*Ping* init()\n");
-
- if (host == null || host == "") {
- return false;
- }
+ public void init(string host, uint repeat_count, uint data_block_size,
+ uint dscp, uint32 interval_time_out)
+ throws BasicManagementTestError {
+ this.command = { "ping" };
+ this.status = Status.ERROR_INTERNAL;
+ this.additional_info = "";
+ this.success_count = 0;
+ this.failure_count = 0;
+ this.avg_response_time = 0;
+ this.min_response_time = 0;
+ this.max_response_time = 0;
if (repeat_count == 0) {
- repeat_count = PING_DEFAULT_REPEAT_COUNT;
- } else if (repeat_count < PING_MIN_REPEAT_COUNT &&
- repeat_count > PING_MAX_REPEAT_COUNT) {
- return false;
+ repeat_count = DEFAULT_REPEAT_COUNT;
+ } else if (repeat_count < MIN_REPEAT_COUNT &&
+ repeat_count > MAX_REPEAT_COUNT) {
+ throw new BasicManagementTestError.INIT_FAILED
+ ("Invalid repeat count");
}
+ this.command += ("-c %u").printf (repeat_count);
+
+ this.command += ("-W %u").printf (DEFAULT_REPLY_TIMEOUT/1000);
if (interval_time_out == 0) {
- interval_time_out = PING_DEFAULT_REQUEST_INTERVAL_TIMEOUT;
- } else if (interval_time_out < PING_MIN_REQUEST_INTERVAL_TIMEOUT &&
- interval_time_out > PING_MAX_REQUEST_INTERVAL_TIMEOUT) {
- return false;
+ interval_time_out = DEFAULT_REQUEST_INTERVAL_TIMEOUT;
+ } else if (interval_time_out < MIN_REQUEST_INTERVAL_TIMEOUT &&
+ interval_time_out > MAX_REQUEST_INTERVAL_TIMEOUT) {
+ throw new BasicManagementTestError.INIT_FAILED
+ ("Invalid interval timeout");
}
+ this.command += ("-i %u").printf (interval_time_out/1000);
if (data_block_size == 0) {
- data_block_size = PING_DEFAULT_DATA_BLOCK_SIZE;
- } else if (data_block_size < PING_MIN_DATA_BLOCK_SIZE &&
- data_block_size > PING_MAX_DATA_BLOCK_SIZE) {
- return false;
+ data_block_size = DEFAULT_DATA_BLOCK_SIZE;
+ } else if (data_block_size < MIN_DATA_BLOCK_SIZE &&
+ data_block_size > MAX_DATA_BLOCK_SIZE) {
+ throw new BasicManagementTestError.INIT_FAILED
+ ("Invalid data block size");
}
+ this.command += ("-s %u").printf (data_block_size);
if (dscp == 0) {
- dscp = PING_DEFAULT_DSCP;
- } else if (dscp < PING_MIN_DSCP && dscp > PING_MAX_DSCP) {
- return false;
+ dscp = DEFAULT_DSCP;
+ } else if (dscp < MIN_DSCP && dscp > MAX_DSCP) {
+ throw new BasicManagementTestError.INIT_FAILED
+ ("Invalid DSCP");
}
+ this.command += ("-Q %u").printf (dscp >> 2);
- this.host = host;
- this.repeat_count = repeat_count;
- this.data_block_size = data_block_size;
- this.dscp = dscp;
- this.interval_time_out = interval_time_out;
+ if (host == null || host.length < 1) {
+ throw new BasicManagementTestError.INIT_FAILED
+ ("Host name is required");
+ }
- return true;
+ this.command += host;
+ }
+
+ protected override void init_iteration () {
+ base.init_iteration ();
+
+ this.state = ProcessState.INIT;
+ }
+
+ protected override void finish_iteration () {
+ switch (this.execution_state) {
+ case ExecutionState.SPAWN_FAILED:
+ this.status = Status.ERROR_INTERNAL;
+ this.additional_info = "Failed spawn ping";
+ break;
+ default:
+ break;
+ }
+
+ base.finish_iteration ();
+ }
+
+ protected override void handle_error (string line) {
+ if (line.contains ("ping: unknown host")) {
+ this.status = Status.ERROR_CANNOT_RESOLVE_HOSTNAME;
+ this.execution_state = ExecutionState.COMPLETED;
+ } else if (line.contains ("ping:")) {
+ this.status = Status.ERROR_OTHER;
+ this.additional_info = line.substring ("ping:".length).strip ();
+ this.execution_state = ExecutionState.COMPLETED;
+ }
+ }
+
+ protected override void handle_output (string line) {
+ line.strip ();
+ if (this.state == ProcessState.INIT) {
+ if (line.contains ("statistics ---")) {
+ this.state = ProcessState.STATISTICS;
+ this.status = Status.SUCCESS;
+ }
+ } else if (this.state == ProcessState.STATISTICS) {
+ if (line.contains ("packets transmitted")) {
+ this.state = ProcessState.RTT;
+
+ var rtt_values = line.split (", ", 3);
+ uint tx = int.parse (rtt_values[0].split (" ", 3)[0]);
+ uint rx = int.parse (rtt_values[1].split (" ", 3)[0]);
+ this.failure_count = tx - rx;
+ this.success_count = rx;
+ }
+ } else if (this.state == ProcessState.RTT) {
+ if (line.contains ("min/avg/max")) {
+ this.execution_state = ExecutionState.COMPLETED;
+
+ var rtt = line.split ("=", 2);
+ if (rtt.length >= 2) {
+ var rtt_values = rtt[1].split ("/", 4);
+ if (rtt_values.length >= 3) {
+ this.avg_response_time = (uint) Math.round (
+ double.parse (rtt_values[0]));
+ this.min_response_time = (uint) Math.round (
+ double.parse (rtt_values[1]));
+ this.max_response_time = (uint) Math.round (
+ double.parse (rtt_values[2]));
+ }
+ }
+ }
+ }
}
public void get_results(out string status, out string additional_info,
out uint success_count, out uint failure_count,
- out uint32 average_response_time,
+ out uint32 avg_response_time,
out uint32 min_response_time,
out uint32 max_response_time) {
- stdout.printf("*Ping* get_results()\n");
-
- status = this.status;
+ status = this.status.to_string ();
additional_info = this.additional_info;
success_count = this.success_count;
failure_count = this.failure_count;
- average_response_time = this.average_response_time;
+ avg_response_time = this.avg_response_time;
min_response_time = this.min_response_time;
max_response_time = this.max_response_time;
}
diff --git a/src/librygel-core/rygel-basic-management.vala b/src/librygel-core/rygel-basic-management.vala
index 1ed10f5..538c88b 100644
--- a/src/librygel-core/rygel-basic-management.vala
+++ b/src/librygel-core/rygel-basic-management.vala
@@ -108,7 +108,8 @@ public class Rygel.BasicManagement : Service {
BasicManagementTest.ExecutionState execution_state = bm_test.execution_state;
if ((execution_state == BasicManagementTest.ExecutionState.REQUESTED) ||
- (execution_state == BasicManagementTest.ExecutionState.REQUESTED)) {
+ (execution_state == BasicManagementTest.ExecutionState.IN_PROGRESS)) {
+
this.tests_map.set (bm_test.id, bm_test);
this.notify ("TestIDs", typeof (string),
create_test_ids_list (false));
@@ -134,7 +135,6 @@ public class Rygel.BasicManagement : Service {
update_test_ids_lists (bm_test);
/* TODO: decide if test should really execute now */
-
bm_test.execute.begin ((obj,res) => {
try {
bm_test.execute.end (res);
@@ -278,14 +278,15 @@ public class Rygel.BasicManagement : Service {
out dscp);
var ping = new BasicManagementTestPing();
- if (!ping.init (host, repeat_count, interval_time_out,
- data_block_size, dscp)) {
- action.return_error (402, _("Invalid argument"));
+ try {
+ ping.init (host, repeat_count, interval_time_out, data_block_size,
+ dscp);
- return;
+ this.add_test_and_return_action (ping as BasicManagementTest,
+ action);
+ } catch (BasicManagementTestError e) {
+ action.return_error (402, _("Invalid argument"));
}
-
- this.add_test_and_return_action (ping as BasicManagementTest, action);
}
private void ping_result_cb (Service cm,
@@ -304,13 +305,13 @@ public class Rygel.BasicManagement : Service {
string status, additional_info;
uint success_count, failure_count;
- uint32 average_response_time, min_response_time, max_response_time;
+ uint32 avg_response_time, min_response_time, max_response_time;
(bm_test as BasicManagementTestPing).get_results (out status,
out additional_info,
out success_count,
out failure_count,
- out average_response_time,
+ out avg_response_time,
out min_response_time,
out max_response_time);
@@ -328,7 +329,7 @@ public class Rygel.BasicManagement : Service {
failure_count,
"AverageResponseTime",
typeof (uint32),
- average_response_time,
+ avg_response_time,
"MinimumResponseTime",
typeof (uint32),
min_response_time,
@@ -367,8 +368,8 @@ public class Rygel.BasicManagement : Service {
var nslookup = new BasicManagementTestNSLookup();
try {
- nslookup.init (hostname, dns_server,
- repeat_count, interval_time_out);
+ nslookup.init (hostname, dns_server, repeat_count,
+ interval_time_out);
this.add_test_and_return_action (nslookup as BasicManagementTest,
action);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]