1 module tagion.testbench.dart.dart_middle_branch;
2 // Default import list for bdd
3 import std.algorithm : filter, map;
4 import std.file : mkdirRecurse;
5 import std.format : format;
6 import std.range;
7 import std.stdio : writefln;
8 import std.typecons : Tuple;
9 import tagion.basic.Types : Buffer, mut;
10 import tagion.behaviour;
11 import tagion.communication.HiRPC;
12 import tagion.crypto.SecureInterfaceNet : HashNet, SecureNet;
13 import tagion.crypto.Types : Fingerprint;
14 import tagion.dart.DART : DART;
15 import tagion.dart.DARTBasic : DARTIndex, dartIndex;
16 import tagion.dart.DARTFakeNet;
17 import tagion.dart.DARTFile : DARTFile;
18 import tagion.dart.DARTRim;
19 import tagion.dart.Recorder : Archive, RecordFactory;
20 import tagion.hibon.Document;
21 import tagion.hibon.HiBONJSON : toPretty;
22 import tagion.hibon.HiBONRecord;
23 import tagion.testbench.dart.dart_helper_functions : getFingerprints, getRead, getRim, goToSplit;
24 import tagion.testbench.dart.dartinfo;
25 import tagion.testbench.tools.Environment;
26 
27 enum feature = Feature(
28             "Dart snap middle branch",
29             [
30         "All test in this bdd should use dart fakenet. This test covers after a archive has been removed, if when adding a new archive on top, that the branch snaps back."
31 ]);
32 
33 alias FeatureContext = Tuple!(
34         AddOneArchiveAndSnap, "AddOneArchiveAndSnap",
35         FeatureGroup*, "result"
36 );
37 
38 @safe @Scenario("Add one archive and snap.",
39         [])
40 class AddOneArchiveAndSnap {
41 
42     DART db;
43 
44     DARTIndex doc_dart_index;
45     Fingerprint doc_fingerprint;
46     Fingerprint bullseye;
47     const DartInfo info;
48 
49     this(const DartInfo info) {
50         this.info = info;
51     }
52 
53     @Given("I have a dartfile with one archive.")
54     Document archive() {
55         Exception dart_exception;
56         db = new DART(info.net, info.dartfilename, dart_exception);
57         check(dart_exception is null, format("Failed to open DART %s", dart_exception.msg));
58         const bullseye = db.bullseye();
59 
60         const doc = DARTFakeNet.fake_doc(info.deep_table[1]);
61         const doc_bullseye = dartIndex(info.net, doc);
62 
63         check(bullseye == doc_bullseye, "Bullseye not equal to doc");
64         // db.dump;
65         return result_ok;
66     }
67 
68     @Given("I add one archive2 in the same sector.")
69     Document sector() {
70         auto recorder = db.recorder();
71         const doc = DARTFakeNet.fake_doc(info.deep_table[2]);
72         recorder.add(doc);
73         pragma(msg, "fixme(cbr): Should this be Fingerprint or DARTIndex");
74         doc_dart_index = recorder[].front.dart_index.mut;
75         doc_fingerprint = recorder[].front.fingerprint.mut;
76         bullseye = db.modify(recorder);
77 
78         check(doc_fingerprint != bullseye, "Bullseye not updated");
79         // db.dump();
80         return result_ok;
81     }
82 
83     @Then("the branch should snap back.")
84     Document back() {
85         const doc = goToSplit(Rims.root, info.hirpc, db);
86 
87         const DARTIndex[] fingerprints = getFingerprints(doc, db);
88         const read_doc = getRead(fingerprints, info.hirpc, db);
89         const recorder = db.recorder(read_doc);
90 
91         foreach (i, data; recorder[].enumerate) {
92             const(ulong) archive = data.filed[info.FAKE].get!ulong;
93             check(archive == info.deep_table[i + 1], "Retrieved data not the same");
94         }
95 
96         auto rim_fingerprints = DARTFile.Branches(doc)
97             .fingerprints
98             .filter!(f => !f.empty)
99             .array;
100 
101         foreach (i; 0 .. 2) {
102             const rim = Rims(rim_fingerprints[i][0 .. 3]);
103             const rim_doc = getRim(rim, info.hirpc, db);
104 
105             check(RecordFactory.Recorder.isRecord(rim_doc), format("branch %s not snapped back", rim));
106         }
107 
108         return result_ok;
109     }
110 
111 }