1 /**
2 Copyright: Copyright (c) 2018, Joakim Brännström. All rights reserved.
3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
4 Author: Joakim Brännström (joakim.brannstrom@gmx.com)
5 */
6 module config;
7 
8 public import logger = std.experimental.logger;
9 public import std;
10 
11 public import unit_threaded.assertions;
12 
13 string dsnapshotPath() {
14     foreach (a; ["../build/dsnapshot"].filter!(a => exists(a)))
15         return a.absolutePath;
16     assert(0, "unable to find a dsnapshot binary");
17 }
18 
19 auto executeDsnapshot(string[] args, string workDir) {
20     return execute([dsnapshotPath] ~ args, null, Config.none, size_t.max, workDir);
21 }
22 
23 /// Path to where data used for integration tests exists
24 string testData() {
25     return "testdata".absolutePath;
26 }
27 
28 string inTestData(string p) {
29     return buildPath(testData, p);
30 }
31 
32 string tmpDir() {
33     return "build/test".absolutePath;
34 }
35 
36 auto makeTestArea(string file = __FILE__, int line = __LINE__) {
37     return TestArea(file, line);
38 }
39 
40 struct TestArea {
41     const string sandboxPath;
42 
43     this(string file, int line) {
44         prepare();
45         sandboxPath = buildPath(tmpDir, file.baseName ~ line.to!string).absolutePath;
46 
47         if (exists(sandboxPath)) {
48             rmdirRecurse(sandboxPath);
49         }
50         mkdirRecurse(sandboxPath);
51     }
52 
53     auto execDs(Args...)(auto ref Args args_) {
54         string[] args;
55         static foreach (a; args_)
56             args ~= a;
57         args ~= ["-v", "trace"];
58         auto res = executeDsnapshot(args, sandboxPath);
59         try {
60             File(inSandboxPath("command.log"), "w").write(res.output);
61         } catch (Exception e) {
62         }
63         return res;
64     }
65 
66     string[] findFile(string subDir, string basename) {
67         string[] files;
68         foreach (p; dirEntries(buildPath(sandboxPath, subDir), SpanMode.depth).filter!(
69                 a => a.baseName == basename))
70             files ~= p.name;
71         logger.errorf(files.length == 0, "File %s not found in ", basename, subDir);
72         return files;
73     }
74 
75     string inSandboxPath(in string fileName) @safe pure nothrow const {
76         import std.path : buildPath;
77 
78         return buildPath(sandboxPath, fileName);
79     }
80 }
81 
82 void writeConfigFromTemplate(Args...)(auto ref TestArea ta, string tmplPath, auto ref Args args) {
83     const tmpl = readText(tmplPath);
84     File(ta.inSandboxPath(".dsnapshot.toml"), "w").writef(tmpl, args);
85 }
86 
87 void writeDummyData(ref TestArea ta, string content) {
88     const src = ta.inSandboxPath("src");
89     if (!exists(src))
90         mkdir(src);
91     File(buildPath(src, "file.txt"), "w").write(content);
92 }
93 
94 private:
95 
96 shared(bool) g_isPrepared = false;
97 
98 void prepare() {
99     synchronized {
100         if (g_isPrepared)
101             return;
102         g_isPrepared = true;
103 
104         // prepare by cleaning up
105         if (exists(tmpDir))
106             rmdirRecurse(tmpDir);
107     }
108 }