1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
pub mod db;
pub mod server;

use assert_fs::TempDir;
use lazy_static::lazy_static;
use rand::Rng;
use std::env;
use std::path::PathBuf;
use std::sync::atomic::{AtomicU32, Ordering};

use self::{db::DbBuilder, server::ServerBootstrapper};
use crate::common::data::ArbitrarySnapshotGenerator;
use crate::common::{data, server::Server};
use data::Snapshot;
use server::ServerBootstrapperError;

pub fn get_exe() -> PathBuf {
    const VIT_BIN_NAME: &str = env!("VIT_BIN_NAME");
    let mut path = get_working_directory();
    path.push(VIT_BIN_NAME);
    if cfg!(windows) {
        path.set_extension("exe");
    }
    assert!(
        path.is_file(),
        "File does not exist: {:?}, pwd: {:?}",
        path,
        env::current_dir()
    );
    path
}

pub fn get_cli_exe() -> PathBuf {
    const VIT_BIN_NAME: &str = env!("VIT_CLI_NAME");
    let mut path = get_working_directory();
    path.push(VIT_BIN_NAME);
    if cfg!(windows) {
        path.set_extension("exe");
    }
    assert!(
        path.is_file(),
        "File does not exist: {:?}, pwd: {:?}",
        path,
        env::current_dir()
    );
    path
}

/// Gets working directory
/// Uses std::env::current_exe() for this purpose.
/// Current exe directory is ./target/{profile}/deps/{app_name}.exe
/// Function returns ./target/{profile}
fn get_working_directory() -> PathBuf {
    let mut output_directory: PathBuf = std::env::current_exe().unwrap();

    output_directory.pop();

    if output_directory.ends_with("deps") {
        output_directory.pop();
    }
    output_directory
}

lazy_static! {
    static ref NEXT_AVAILABLE_PORT_NUMBER: AtomicU32 = {
        let initial_port = rand::thread_rng().gen_range(6000, 10999);
        AtomicU32::new(initial_port)
    };
}

pub fn get_available_port() -> u32 {
    NEXT_AVAILABLE_PORT_NUMBER.fetch_add(1, Ordering::SeqCst)
}

pub fn quick_start(temp_dir: &TempDir) -> Result<(Server, Snapshot), ServerBootstrapperError> {
    let snapshot = ArbitrarySnapshotGenerator::default().snapshot();

    let db_path = DbBuilder::new().with_snapshot(&snapshot).build()?;

    let server = ServerBootstrapper::new()
        .with_db_path(db_path)
        .start(temp_dir)?;

    if !server.is_up(&snapshot.token_hash()) {
        return Err(ServerBootstrapperError::FailToBootstrap);
    }

    Ok((server, snapshot))
}

pub fn empty_db() -> String {
    DbBuilder::new().build().unwrap()
}