From 4b9dde655e8df12434cc28078f915a03584c418a Mon Sep 17 00:00:00 2001
From: librelois <elois@ifee.fr>
Date: Mon, 23 Apr 2018 17:45:33 +0200
Subject: [PATCH] [enh] add all wotb methods and all js tests (except io file)
---
lib/index.js | 44 +++++---
native/Cargo.lock | 6 +-
native/Cargo.toml | 2 +-
native/src/lib.rs | 129 +++++++++++++++++++-----
package.json | 2 +-
tests/test.js | 251 +++++++++++++++++++++++++++++++++++++++++++++-
6 files changed, 384 insertions(+), 50 deletions(-)
diff --git a/lib/index.js b/lib/index.js
index ba91367..d096f0c 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -63,25 +63,19 @@ const WotB = {
},
getEnabled: function() {
- var wot_size = addon.get_wot_size(this.instanceID);
- var enabled_array = new Array();
- for (let i = 0; i < wot_size; i++) {
- if (addon.is_enabled(this.instanceID, i)) {
- enabled_array.push(i);
- }
- }
- return enabled_array;
+ return addon.get_enabled(this.instanceID);
},
getDisabled: function() {
- var wot_size = addon.get_wot_size(this.instanceID);
- var enabled_array = new Array();
- for (let i = 0; i < wot_size; i++) {
- if (!addon.is_enabled(this.instanceID, i)) {
- enabled_array.push(i);
- }
- }
- return enabled_array;
+ return addon.get_disabled(this.instanceID);
+ },
+
+ getSentries: function(sentry_requirement) {
+ return addon.get_sentries(this.instanceID, sentry_requirement);
+ },
+
+ getNonSentries: function(sentry_requirement) {
+ return addon.get_non_sentries(this.instanceID, sentry_requirement);
},
existsLink: function(source, target) {
@@ -118,6 +112,24 @@ const WotB = {
return distance_result.outdistanced;
},
+ detailedDistance: function(node, sentry_requirement, step_max, x_percent) {
+ var distance_result = addon.compute_distance(this.instanceID, node, sentry_requirement, step_max, x_percent);
+ return {
+ nbReached: distance_result.reached,
+ nbSuccess: distance_result.success,
+ nbSentries: distance_result.sentries,
+ isOutdistanced: distance_result.outdistanced
+ };
+ },
+
+ detailedDistanceV2: function(node, sentry_requirement, step_max, x_percent) {
+ return addon.compute_distance(this.instanceID, node, sentry_requirement, step_max, x_percent);
+ },
+
+ getPaths: function(from, to, step_max) {
+ return addon.find_paths(this.instanceID, from, to, step_max);
+ },
+
clear: function() {
return addon.remove_wot(this.instanceID);
}
diff --git a/native/Cargo.lock b/native/Cargo.lock
index 095b10c..61a44fc 100644
--- a/native/Cargo.lock
+++ b/native/Cargo.lock
@@ -76,7 +76,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "duniter-wotb"
-version = "0.7.1"
+version = "0.8.0-a0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -352,7 +352,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "wotb-rs"
version = "0.1.0"
dependencies = [
- "duniter-wotb 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "duniter-wotb 0.8.0-a0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"neon 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
"neon-build 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -369,7 +369,7 @@ dependencies = [
"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
"checksum cslice 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "697c714f50560202b1f4e2e09cd50a421881c83e9025db75d15f276616f04f40"
-"checksum duniter-wotb 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "834b85bd66552e19e45245c3fe2f96bd350fa11adad679902ae6a127ed9f4dc1"
+"checksum duniter-wotb 0.8.0-a0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "873a948b6755405ec2da9f25b1266fcfaf45f9ef043b08e01eab4a6f91e9e6ad"
"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
diff --git a/native/Cargo.toml b/native/Cargo.toml
index 715d044..6cf4c9e 100644
--- a/native/Cargo.toml
+++ b/native/Cargo.toml
@@ -15,4 +15,4 @@ neon-build = "0.1.22"
[dependencies]
neon = "0.1.22"
num_cpus = "1.8.0"
-duniter-wotb = "0.7.1"
+duniter-wotb = "0.8.0-a0.5"
diff --git a/native/src/lib.rs b/native/src/lib.rs
index 846077e..52005fb 100644
--- a/native/src/lib.rs
+++ b/native/src/lib.rs
@@ -4,15 +4,19 @@ extern crate neon;
extern crate duniter_wotb;
extern crate num_cpus;
-use duniter_wotb::rusty::RustyWebOfTrust;
-use duniter_wotb::{HasLinkResult, NewLinkResult, NodeId, RemLinkResult, WebOfTrust, WotDistance,
- WotDistanceParameters};
+use duniter_wotb::data::rusty::RustyWebOfTrust;
+use duniter_wotb::data::{HasLinkResult, NewLinkResult, NodeId, RemLinkResult, WebOfTrust};
+use duniter_wotb::operations::distance::{DistanceCalculator, RustyDistanceCalculator, WotDistance,
+ WotDistanceParameters};
+use duniter_wotb::operations::path::{PathFinder, RustyPathFinder};
use neon::js::{JsArray, JsBoolean, JsInteger, JsNumber, JsObject, JsString, Object};
use neon::vm::{Call, JsResult};
use std::collections::HashMap;
use std::ops::{Deref, DerefMut};
static mut WOT_INSTANCES: Option<HashMap<usize, Box<RustyWebOfTrust>>> = None;
+static DISTANCE_CALCULATOR: RustyDistanceCalculator = RustyDistanceCalculator {};
+static PATH_FINDER: RustyPathFinder = RustyPathFinder {};
fn get_wots() -> &'static mut HashMap<usize, Box<RustyWebOfTrust>> {
unsafe {
@@ -82,9 +86,13 @@ fn new_memory_instance(call: Call) -> JsResult<JsInteger> {
fn mem_copy(call: Call) -> JsResult<JsInteger> {
let scope = call.scope;
- let instance_id = try!(try!(call.arguments.require(scope, 0)).check::<JsInteger>()).value() as usize;
+ let instance_id =
+ try!(try!(call.arguments.require(scope, 0)).check::<JsInteger>()).value() as usize;
let wots = get_wots();
- let wot_copy = wots.get(&instance_id).expect("This instance don't exist !").deref().clone();
+ let wot_copy = wots.get(&instance_id)
+ .expect("This instance don't exist !")
+ .deref()
+ .clone();
let mut new_instance_id = 0;
while wots.contains_key(&new_instance_id) {
new_instance_id += 1;
@@ -123,18 +131,18 @@ fn is_enabled(call: Call) -> JsResult<JsBoolean> {
}
}
-fn get_enabled(call: Call) -> JsResult<JsObject> {
+fn get_enabled(call: Call) -> JsResult<JsArray> {
let scope = call.scope;
let instance_id = try!(try!(call.arguments.require(scope, 0)).check::<JsInteger>()).value();
let enabled = get_mut_wot(instance_id as usize).get_enabled();
- let mut js_array = JsObject::new(scope);
+ let mut js_array = JsArray::new(scope, enabled.len() as u32);
let mut index: u32 = 0;
for node_id in enabled {
- let _bool = JsObject::set(
+ let _bool = try!(JsArray::set(
*js_array.deref_mut(),
index,
JsInteger::new(scope, node_id.0 as i32),
- );
+ ));
index += 1;
}
Ok(js_array)
@@ -147,11 +155,50 @@ fn get_disabled(call: Call) -> JsResult<JsArray> {
let js_array = JsArray::new(scope, disabled.len() as u32);
let mut index: u32 = 0;
for node_id in disabled {
- let _bool = JsArray::set(
+ let _bool = try!(JsArray::set(
+ *js_array.deref(),
+ index,
+ JsInteger::new(scope, node_id.0 as i32),
+ ));
+ index += 1;
+ }
+ Ok(js_array)
+}
+
+fn get_sentries(call: Call) -> JsResult<JsArray> {
+ let scope = call.scope;
+ let instance_id = try!(try!(call.arguments.require(scope, 0)).check::<JsInteger>()).value();
+ let sentry_requirement =
+ try!(try!(call.arguments.require(scope, 1)).check::<JsInteger>()).value();
+ let sentries = get_mut_wot(instance_id as usize).get_sentries(sentry_requirement as usize);
+ let js_array = JsArray::new(scope, sentries.len() as u32);
+ let mut index: u32 = 0;
+ for node_id in sentries {
+ let _bool = try!(JsArray::set(
+ *js_array.deref(),
+ index,
+ JsInteger::new(scope, node_id.0 as i32),
+ ));
+ index += 1;
+ }
+ Ok(js_array)
+}
+
+fn get_non_sentries(call: Call) -> JsResult<JsArray> {
+ let scope = call.scope;
+ let instance_id = try!(try!(call.arguments.require(scope, 0)).check::<JsInteger>()).value();
+ let sentry_requirement =
+ try!(try!(call.arguments.require(scope, 1)).check::<JsInteger>()).value();
+ let non_sentries =
+ get_mut_wot(instance_id as usize).get_non_sentries(sentry_requirement as usize);
+ let js_array = JsArray::new(scope, non_sentries.len() as u32);
+ let mut index: u32 = 0;
+ for node_id in non_sentries {
+ let _bool = try!(JsArray::set(
*js_array.deref(),
index,
JsInteger::new(scope, node_id.0 as i32),
- );
+ ));
index += 1;
}
Ok(js_array)
@@ -252,6 +299,7 @@ fn compute_distance(call: Call) -> JsResult<JsObject> {
step_max,
x_percent,
};
+ let wot = get_wot(instance_id as usize);
let WotDistance {
sentries,
success,
@@ -259,43 +307,71 @@ fn compute_distance(call: Call) -> JsResult<JsObject> {
reached,
reached_at_border,
outdistanced,
- } = get_wot(instance_id as usize)
- .compute_distance(distance_params)
+ } = DISTANCE_CALCULATOR
+ .compute_distance(wot, distance_params)
.unwrap();
let js_object = JsObject::new(scope);
- let _bool = JsObject::set(
+ let _bool = try!(JsObject::set(
*js_object.deref(),
"sentries",
JsInteger::new(scope, sentries as i32),
- );
- let _bool = JsObject::set(
+ ));
+ let _bool = try!(JsObject::set(
*js_object.deref(),
"success",
JsInteger::new(scope, success as i32),
- );
- let _bool = JsObject::set(
+ ));
+ let _bool = try!(JsObject::set(
*js_object.deref(),
"success_at_border",
JsInteger::new(scope, success_at_border as i32),
- );
- let _bool = JsObject::set(
+ ));
+ let _bool = try!(JsObject::set(
*js_object.deref(),
"reached",
JsInteger::new(scope, reached as i32),
- );
- let _bool = JsObject::set(
+ ));
+ let _bool = try!(JsObject::set(
*js_object.deref(),
"reached_at_border",
JsInteger::new(scope, reached_at_border as i32),
- );
- let _bool = JsObject::set(
+ ));
+ let _bool = try!(JsObject::set(
*js_object.deref(),
"outdistanced",
JsBoolean::new(scope, outdistanced),
- );
+ ));
Ok(js_object)
}
+fn find_paths(call: Call) -> JsResult<JsArray> {
+ let scope = call.scope;
+ let instance_id =
+ try!(try!(call.arguments.require(scope, 0)).check::<JsInteger>()).value() as usize;
+ let from = try!(try!(call.arguments.require(scope, 1)).check::<JsInteger>()).value() as u32;
+ let to = try!(try!(call.arguments.require(scope, 2)).check::<JsInteger>()).value() as u32;
+ let step_max = try!(try!(call.arguments.require(scope, 3)).check::<JsInteger>()).value() as u32;
+ let wot = get_wot(instance_id as usize);
+ let paths = PATH_FINDER.find_paths(wot, NodeId(from as usize), NodeId(to as usize), step_max);
+ let mut i: u32 = 0;
+ let js_paths = JsArray::new(scope, paths.len() as u32);
+ for path in paths {
+ let mut j: u32 = 0;
+ let js_path = JsArray::new(scope, path.len() as u32);
+ for node_id in path {
+ let _bool = try!(JsArray::set(
+ *js_path.deref(),
+ j,
+ JsInteger::new(scope, node_id.0 as i32),
+ ));
+ j += 1;
+ }
+ let _bool = try!(JsArray::set(*js_paths.deref(), i, js_path,));
+ i += 1;
+ }
+ Ok(js_paths)
+}
+
fn remove_wot(call: Call) -> JsResult<JsBoolean> {
let scope = call.scope;
let instance_id =
@@ -319,6 +395,8 @@ register_module!(m, {
m.export("is_enabled", is_enabled)?;
m.export("get_enabled", get_enabled)?;
m.export("get_disabled", get_disabled)?;
+ m.export("get_sentries", get_sentries)?;
+ m.export("get_non_sentries", get_non_sentries)?;
m.export("exist_link", exist_link)?;
m.export("set_max_links", set_max_links)?;
m.export("add_node", add_node)?;
@@ -327,6 +405,7 @@ register_module!(m, {
m.export("add_link", add_link)?;
m.export("rem_link", rem_link)?;
m.export("compute_distance", compute_distance)?;
+ m.export("find_paths", find_paths)?;
m.export("remove_wot", remove_wot)?;
Ok(())
});
diff --git a/package.json b/package.json
index 4785100..292765f 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,7 @@
"main": "lib/index.js",
"repository": {
"type": "git",
- "url": "https://git.duniter.org/nodes/typescript/wotb-rust"
+ "url": "https://git.duniter.org/nodes/typescript/wotb-rs"
},
"author": "librelois <elois@ifee.fr>",
"license": "AGPL-3.0",
diff --git a/tests/test.js b/tests/test.js
index 2ebc803..bcdf8fc 100644
--- a/tests/test.js
+++ b/tests/test.js
@@ -30,7 +30,7 @@ function testSuite(title, mode) {
if (mode === FILE_MODE) {
let wot = addon.newFileInstance(FILE);
launchTests(wot, () => {
- wot.drop();
+ wot.clear();
wot.setMaxCert(3);
});
} else {
@@ -60,12 +60,16 @@ function testSuite(title, mode) {
should.equal(wot.addNode(), 0);
should.equal(wot.getWoTSize(), 1);
should.equal(wot.isEnabled(0), true);
- should.equal(wot.getEnabled().length, 1);
+ var enabled = wot.getEnabled();
+ should.equal(enabled.length, 1);
+ should.equal(enabled[0], 0);
should.equal(wot.getDisabled().length, 0);
// Add another
should.equal(wot.addNode(), 1);
should.equal(wot.getWoTSize(), 2);
- should.equal(wot.getEnabled().length, 2);
+ var enabled = wot.getEnabled();
+ should.equal(enabled.length, 2);
+ should.equal(enabled[1], 1);
should.equal(wot.getDisabled().length, 0);
// Add 10 nodes
for (let i = 0; i < 10; i++) {
@@ -190,6 +194,13 @@ function testSuite(title, mode) {
* 3 --> 2
*/
should.equal(wot.getWoTSize(), 12);
+ should.equal(wot.getSentries(FROM_1_LINK_SENTRIES).length, 1);
+ should.equal(wot.getSentries(FROM_1_LINK_SENTRIES)[0], 2);
+ should.equal(wot.getSentries(FROM_2_LINKS_SENTRIES).length, 0);
+ should.equal(wot.getSentries(FROM_3_LINKS_SENTRIES).length, 0);
+ should.equal(wot.getNonSentries(FROM_1_LINK_SENTRIES).length, 11); // 12 - 1 = 11
+ should.equal(wot.getNonSentries(FROM_2_LINKS_SENTRIES).length, 12); // 12 - 0 = 12
+ should.equal(wot.getNonSentries(FROM_3_LINKS_SENTRIES).length, 12); // 12 - 0 = 12
should.equal(wot.isOutdistanced(0, FROM_1_LINK_SENTRIES, MAX_DISTANCE_1, X_PERCENT), __OK__); // OK: 2 --> 0
should.equal(wot.isOutdistanced(0, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_1, X_PERCENT), __OK__); // OK: 2 --> 0
should.equal(wot.isOutdistanced(0, FROM_3_LINKS_SENTRIES, MAX_DISTANCE_1, X_PERCENT), __OK__); // OK: no sentry with 3 links issued
@@ -199,6 +210,19 @@ function testSuite(title, mode) {
wot.addLink(2, 3);
should.equal(wot.getWoTSize(), 12);
+ should.equal(wot.getSentries(FROM_1_LINK_SENTRIES).length, 3);
+ should.equal(wot.getSentries(FROM_1_LINK_SENTRIES)[0], 1);
+ should.equal(wot.getSentries(FROM_1_LINK_SENTRIES)[1], 2);
+ should.equal(wot.getSentries(FROM_1_LINK_SENTRIES)[2], 3);
+ should.equal(wot.getSentries(FROM_2_LINKS_SENTRIES).length, 1);
+ should.equal(wot.getSentries(FROM_2_LINKS_SENTRIES)[0], 3);
+ should.equal(wot.getSentries(FROM_3_LINKS_SENTRIES).length, 0);
+ should.equal(wot.getNonSentries(FROM_1_LINK_SENTRIES).length, 9); // 12 - 3 = 9
+ should.equal(wot.getNonSentries(FROM_2_LINKS_SENTRIES).length, 11); // 12 - 1 = 11
+ should.equal(wot.getNonSentries(FROM_3_LINKS_SENTRIES).length, 12); // 12 - 0 = 12
+ should.equal(wot.getPaths(3, 0, MAX_DISTANCE_1).length, 0); // KO
+ should.equal(wot.getPaths(3, 0, MAX_DISTANCE_2).length, 1); // It exists 3 --> 2 --> 0
+ should.equal(wot.getPaths(3, 0, MAX_DISTANCE_2)[0].length, 3); // It exists 3 --> 2 --> 0
should.equal(wot.isOutdistanced(0, FROM_1_LINK_SENTRIES, MAX_DISTANCE_1, X_PERCENT), __OUTDISTANCED__); // KO: No path 3 --> 0
should.equal(wot.isOutdistanced(0, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_1, X_PERCENT), __OUTDISTANCED__); // KO: No path 3 --> 0
should.equal(wot.isOutdistanced(0, FROM_3_LINKS_SENTRIES, MAX_DISTANCE_1, X_PERCENT), __OK__); // OK: no sentry with 3 links issued
@@ -220,7 +244,9 @@ function testSuite(title, mode) {
it('should work with member 3 disabled', function() {
// With member 3 disabled (non-member)
should.equal(wot.setEnabled(false, 3), false);
- should.equal(wot.getDisabled().length, 1);
+ let disabled_nodes = wot.getDisabled();
+ should.equal(disabled_nodes.length, 1);
+ should.equal(disabled_nodes[0], 3);
should.equal(wot.isOutdistanced(0, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_1, X_PERCENT), __OK__); // OK: No path 3 --> 0, but is disabled
});
@@ -241,5 +267,222 @@ function testSuite(title, mode) {
after(cleanInstance);
}));
+
+ describe('Building a larger WoT', newInstance((wot, cleanInstance) => {
+
+ before(() => {
+ cleanInstance();
+ /**
+ * We build WoT:
+ *
+ * 0 --> 1 --> 2 --> 4 --> 5 <==> 6 --> 7
+ * ^
+ * ||
+ * ##==> 3 <-- 8 <-- 9 <========##
+ * | ||
+ * `> 10 <==> 11 <===##
+ */
+ // Add nodes
+ for (let i = 0; i < 12; i++) {
+ should.equal(wot.addNode(), i);
+ }
+ // First line
+ should.equal(wot.addLink(0, 1), 1);
+ should.equal(wot.addLink(1, 2), 1);
+ should.equal(wot.addLink(2, 4), 1);
+ should.equal(wot.addLink(4, 5), 1);
+ should.equal(wot.addLink(5, 6), 1);
+ should.equal(wot.addLink(6, 7), 1);
+ should.equal(wot.addLink(6, 5), 2);
+ // 2n level
+ should.equal(wot.addLink(2, 3), 1);
+ should.equal(wot.addLink(3, 2), 2);
+ should.equal(wot.addLink(8, 3), 2);
+ should.equal(wot.addLink(9, 8), 1);
+ // 3rd level
+ should.equal(wot.addLink(8, 10), 1);
+ should.equal(wot.addLink(10, 11), 1);
+ should.equal(wot.addLink(11, 10), 2);
+ should.equal(wot.addLink(11, 9), 1);
+ should.equal(wot.addLink(9, 11), 2);
+
+ should.equal(wot.getWoTSize(), 12);
+ return Promise.resolve();
+ });
+
+ it('should have an initial size of 0', function() {
+ should.equal(wot.getWoTSize(), 12);
+ });
+
+ describe('testing around 2 with d = 1', () => {
+
+ /**
+ * Sentries of 1 link (X are not sentries):
+ *
+ * X --> 1 --> 2 --> 4 --> 5 <==> 6 --> X
+ * ^
+ * ||
+ * ##==> 3 <-- 8 <-- 9 <========##
+ * | ||
+ * `> 10 <==> 11 <===##
+ */
+ // => It can be seen 1..6, 8..11 = 10 sentries
+ // => MINUS the sentry #2 (which is tested and is not to be included)
+ // => 9 sentries TESTED against member#2
+
+ it('should have 10 sentries', function() {
+ should.equal(wot.getSentries(FROM_1_LINK_SENTRIES).length, 10);
+ });
+
+ it('distance k = 1', function() {
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_1, _100_PERCENT), __OUTDISTANCED__);
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_1, 0.5), __OUTDISTANCED__);
+ // 20% of the sentries: OK
+ // => 20% x 9 = 2 sentries to reach
+ // => we have 1 --> 2
+ // => we have 3 --> 2
+ // => OK (1,3)
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_1, 0.2), __OK__);
+ // Who can pass 20% can pass 10%
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_1, 0.1), __OK__);
+ // Can pass 23% (1,98 => 2 sentries)
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_1, 0.22), __OK__);
+ // But cannot pass 23% (2,07 => 3 sentries)
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_1, 0.23), __OUTDISTANCED__);
+ });
+
+ it('distance k = 2', function() {
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_2, _100_PERCENT), __OUTDISTANCED__);
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_2, 0.5), __OUTDISTANCED__);
+ // 33% of the sentries: OK
+ // => 33% x 9 = 3 sentries to reach
+ // With k = 2 we have the following paths:
+ // 1 --> 2
+ // 8 --> 3 --> 2
+ // => OK (1,8,3)
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_2, 0.33), __OK__);
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_2, 0.3), __OK__);
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_2, 0.2), __OK__);
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_2, 0.1), __OK__);
+ // But cannot pass 34% (3,06 => 4 sentries)
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_2, 0.34), __OUTDISTANCED__);
+ });
+
+ it('distance k = 5', function() {
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_5, _100_PERCENT), __OUTDISTANCED__);
+ // 66% of the sentries: OK
+ // => 66% x 9 = 6 sentries to reach
+ // With k = 5 we have the following paths:
+ // 1 --> 2
+ // 10 --> 11 --> 9 --> 8 --> 3 --> 2
+ // => OK (1,10,11,9,8,3)
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_5, 0.66), __OK__);
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_5, 0.3), __OK__);
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_5, 0.2), __OK__);
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_5, 0.1), __OK__);
+ // But cannot pass 67% (6,03 => 7 sentries)
+ should.equal(wot.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_5, 0.67), __OUTDISTANCED__);
+ assert.deepEqual(wot.detailedDistance(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_5, 0.67), {
+ nbReached: 7, // +1 compared to reached sentries, because of member `0`
+ nbSuccess: 6,
+ nbSentries: 9,
+ isOutdistanced: true
+ });
+ });
+ });
+
+ describe('testing around 2 with d = 2', () => {
+ /**
+ * Sentries of 2 links (X are not sentries):
+ *
+ * X --> X --> 2 --> X --> X <==> X --> X
+ * ^
+ * ||
+ * ##==> X <-- X <-- X <========##
+ * | ||
+ * `> X <==> 11 <===##
+ */
+ // => It can be seen 2,6,8,9,11 = 5 sentries
+ // => MINUS the sentry #2 (which is tested and is not to be included)
+ // => 4 sentries
+
+ it('should have 2 sentries', function() {
+ should.equal(wot.getSentries(FROM_2_LINKS_SENTRIES).length, 2);
+ });
+
+ it('distance k = 1', function() {
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_1, _100_PERCENT), __OUTDISTANCED__);
+ // With k = 1 we have no paths
+ // => ALWAYS KO
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_1, 0.99), __OUTDISTANCED__);
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_1, 0.5), __OUTDISTANCED__);
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_1, 0.01), __OUTDISTANCED__);
+ });
+
+ it('distance k = 2', function() {
+ // Always distanced with k = 2
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_2, _100_PERCENT), __OUTDISTANCED__);
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_2, 0.25), __OUTDISTANCED__);
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_2, 0.24), __OUTDISTANCED__);
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_2, 0.251), __OUTDISTANCED__);
+ });
+
+ it('distance k = 3', function() {
+ // Always distanced with k = 2
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_3, _100_PERCENT), __OUTDISTANCED__);
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_3, 0.50), __OUTDISTANCED__);
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_3, 0.49), __OUTDISTANCED__);
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_3, 0.51), __OUTDISTANCED__);
+ });
+
+ it('distance k = 4', function() {
+ // Only 1 sentry at distance 4: always OK
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_4, _100_PERCENT), __OK__);
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_4, 0.75), __OK__);
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_4, 0.01), __OK__);
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_4, 0.99), __OK__);
+ });
+
+ it('distance k = 5', function() {
+ // Only 1 sentry at distance 4: always OK
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_5, _100_PERCENT), __OK__);
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_5, 0.75), __OK__);
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_5, 0.01), __OK__);
+ should.equal(wot.isOutdistanced(2, FROM_2_LINKS_SENTRIES, MAX_DISTANCE_5, 0.99), __OK__);
+ });
+ });
+
+ describe('testing around 2 with d = 3', () => {
+ /**
+ * Sentries of 3 links (X are not sentries):
+ *
+ * X --> X --> 2 --> X --> X <==> X --> X
+ * ^
+ * ||
+ * ##==> X <-- X <-- X <========##
+ * | ||
+ * `> X <==> X <===##
+ */
+ // => It can be seen 2 = 1 sentries
+ // => MINUS the sentry #2 (which is tested and is not to be included)
+ // => 0 sentries
+ // => ALWAYS OK, no sentries to constraint
+
+ it('distance k = 1', function() {
+ should.equal(wot.isOutdistanced(2, FROM_3_LINKS_SENTRIES, MAX_DISTANCE_1, _100_PERCENT), __OK__);
+ should.equal(wot.isOutdistanced(2, FROM_3_LINKS_SENTRIES, MAX_DISTANCE_1, 0.01), __OK__);
+ });
+
+ it('distance k = 2', function() {
+ should.equal(wot.isOutdistanced(2, FROM_3_LINKS_SENTRIES, MAX_DISTANCE_2, _100_PERCENT), __OK__);
+ should.equal(wot.isOutdistanced(2, FROM_3_LINKS_SENTRIES, MAX_DISTANCE_2, 0.01), __OK__);
+ });
+
+ it('distance k = 5', function() {
+ should.equal(wot.isOutdistanced(2, FROM_3_LINKS_SENTRIES, MAX_DISTANCE_5, _100_PERCENT), __OK__);
+ should.equal(wot.isOutdistanced(2, FROM_3_LINKS_SENTRIES, MAX_DISTANCE_5, 0.01), __OK__);
+ });
+ });
+ }));
});
}
\ No newline at end of file
--
GitLab