1 module tagion.testbench.dart.basic_dart_partial_sync; 2 // Default import list for bdd 3 import std.algorithm : each, equal, filter, map, sort; 4 import std.file : mkdirRecurse; 5 import std.format : format; 6 import std.path : buildPath, setExtension; 7 import std.random : MinstdRand0, randomSample, randomShuffle; 8 import std.range; 9 import std.stdio; 10 import std.typecons : Tuple; 11 import tagion.Keywords; 12 import tagion.basic.basic : tempfile; 13 import tagion.behaviour; 14 import tagion.communication.HiRPC; 15 import tagion.crypto.SecureInterfaceNet : HashNet, SecureNet; 16 import tagion.dart.BlockFile : BlockFile; 17 import tagion.dart.DART : DART; 18 import tagion.dart.DARTBasic : DARTIndex, dartIndex; 19 import tagion.dart.DARTFakeNet; 20 import tagion.dart.DARTFile : DARTFile; 21 import tagion.dart.Recorder : Archive, RecordFactory; 22 import tagion.hibon.Document; 23 import tagion.hibon.HiBONJSON : toPretty; 24 import tagion.hibon.HiBONRecord; 25 import tagion.testbench.dart.dart_helper_functions; 26 import tagion.testbench.dart.dartinfo; 27 import tagion.testbench.tools.Environment; 28 import tagion.utils.Random; 29 30 enum feature = Feature( 31 "DARTSynchronization partial sync.", 32 ["All test in this bdd should use dart fakenet."]); 33 34 alias FeatureContext = Tuple!( 35 PartialSync, "PartialSync", 36 FeatureGroup*, "result" 37 ); 38 39 @safe @Scenario("Partial sync.", 40 []) 41 class PartialSync { 42 DART db1; 43 DART db2; 44 45 DARTIndex[] db1_fingerprints; 46 DARTIndex[] db2_fingerprints; 47 48 const ushort angle = 0; 49 const ushort size = 10; 50 51 ulong[][] sector_states; 52 53 DartInfo info; 54 55 this(DartInfo info) { 56 this.info = info; 57 } 58 59 @Given("I have a dartfile1 with pseudo random data.") 60 Document randomData() { 61 check(!info.states.empty, "Pseudo random sequence not generated"); 62 63 mkdirRecurse(info.module_path); 64 // create the dartfile 65 DART.create(info.dartfilename, info.net); 66 67 Exception dart_exception; 68 db1 = new DART(info.net, info.dartfilename, dart_exception); 69 check(dart_exception is null, format("Failed to open DART %s", dart_exception.msg)); 70 71 sector_states = info.states 72 .map!(state => state.list 73 .map!(archive => putInSector(archive, angle, size)).array).array; 74 75 db1_fingerprints = randomAdd(sector_states, MinstdRand0(65), db1); 76 77 return result_ok; 78 } 79 80 @Given("I have added some of the pseudo random data to dartfile2.") 81 Document toDartfile2() { 82 DART.create(info.dartfilename2, info.net); 83 84 Exception dart_exception; 85 db2 = new DART(info.net, info.dartfilename2, dart_exception); 86 check(dart_exception is null, format("Failed to open DART %s", dart_exception.msg)); 87 88 auto partial_sector_states = sector_states.randomSample(sector_states.length / 2, MinstdRand0(423)).array; 89 90 db2_fingerprints = randomAdd(partial_sector_states, MinstdRand0(314), db2); 91 92 check(db1.bullseye != db2.bullseye, "Bullseyes should not be the same"); 93 94 return result_ok; 95 } 96 97 @Given("I synchronize dartfile1 with dartfile2.") 98 Document withDartfile2() { 99 syncDarts(db1, db2, angle, size); 100 return result_ok; 101 } 102 103 @Then("the bullseyes should be the same.") 104 Document theSame() { 105 check(db1.bullseye == db2.bullseye, "Bullseyes not the same"); 106 107 db1.close(); 108 db2.close(); 109 return result_ok; 110 } 111 112 }