1 module tagion.testbench.tools.Environment;
2 
3 import std.algorithm.iteration : map;
4 import std.array;
5 import std.ascii : toUpper;
6 import std.conv;
7 import std.exception;
8 import std.format;
9 import std.path;
10 import std.process;
11 import std.stdio;
12 import std.traits;
13 import std.file : getcwd;
14 import tagion.basic.Types : DOT, FileExtension;
15 import tagion.behaviour.BehaviourFeature;
16 import tagion.behaviour.BehaviourReporter;
17 import tagion.hibon.HiBONFile : fwrite;
18 
19 void error(Args...)(string fmt, Args args) nothrow @trusted {
20     assumeWontThrow(stderr.writefln(fmt, args));
21 }
22 
23 @safe
24 synchronized
25 class Reporter : BehaviourReporter {
26     static string alternative(scope const(FeatureGroup*) feature_group) nothrow {
27 
28         if (feature_group.alternative.length) {
29             try {
30                 return "_" ~ feature_group.alternative
31                     .split
32                     .join("_");
33             }
34             catch (Exception e) {
35                 // Ignore
36                 error("%s", e);
37             }
38         }
39         return null;
40     }
41 
42     const(Exception) before(scope const(FeatureGroup*) feature_group) nothrow {
43         Exception result;
44         try {
45             immutable report_file_name = buildPath(env.bdd_results,
46                     feature_group.info.name ~ alternative(feature_group))
47                 ~ FileExtension.hibon;
48             report_file_name.fwrite(*feature_group);
49         }
50         catch (Exception e) {
51             result = e;
52         }
53         return result;
54     }
55 
56     const(Exception) after(scope const(FeatureGroup*) feature_group) nothrow {
57         return before(feature_group);
58     }
59 }
60 
61 enum Stage {
62     commit,
63     acceptance,
64     performance,
65 }
66 
67 @safe
68 struct Environment {
69     enum platform = "x86_64-linux";
70     string dbin() const {
71         return environment.get("DBIN", buildPath(reporoot, "build", platform, "bin"));
72     }
73 
74     string dlog() const {
75         return environment.get("DLOG", buildPath(reporoot, "logs", platform));
76     }
77 
78     string bdd() const {
79         return environment.get("BDD", buildPath(reporoot, "bdd"));
80     }
81 
82     string bdd_log() const {
83         return environment.get("BDD_LOG", buildPath(dlog, "bdd", test_stage));
84     }
85 
86     string bdd_results() const {
87         return environment.get("BDD_RESULTS", buildPath(bdd_log, "results"));
88     }
89 
90     string reporoot() const {
91         return environment.get("REPOROOT", getcwd);
92     }
93     // string fund;
94     string test_stage() const {
95         return environment.get("TEST_STAGE", "commit");
96     }
97 
98     string seed() const {
99         return environment.get("SEED", "predictable");
100     }
101 
102     const(uint) getSeed() const {
103         import std.bitmanip : binread = read;
104         import tagion.utils.Miscellaneous;
105 
106         auto buf = decode(seed).dup;
107         return buf.binread!uint;
108     }
109 
110     Stage stage() const {
111         switch (test_stage) {
112             static foreach (E; EnumMembers!Stage) {
113         case E.stringof:
114                 return E;
115             }
116         default:
117             //empty
118         }
119 
120         switch (test_stage.to!uint) {
121             static foreach (i; 0 .. EnumMembers!Stage.length) {
122         case i:
123                 return cast(Stage) i;
124             }
125         default:
126             //empty
127         }
128 
129         assert(0, format("variable is not legal %s", test_stage));
130     }
131 }
132 
133 immutable Environment env;
134 
135 import std.stdio;
136 
137 shared static this() {
138     reporter = new Reporter;
139 }