summaryrefslogtreecommitdiffstats
path: root/src/lib/yang/pretests/sysrepo_setup_tests.cc
blob: 6668cc4145e9dbd38101a7cc9cb71dc2f40be1bb (plain)
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <config.h>

#define KEATEST_MODULE
#include <yang/yang_revisions.h>

#include <sysrepo-cpp/Session.hpp>

#include <unordered_map>
#include <sstream>

using namespace std;
using namespace sysrepo;
using namespace isc::yang;

using libyang::S_Context;
using libyang::S_Module;

const string REPOSITORY = SYSREPO_REPO;

/// @brief Returns nicely formed error message if module is missing
///
/// @param name name of the YANG module to complain about
/// @param revision revision of the YANG module
/// @return a text explaining what the problem is and how to fix it
string missingModuleText(const string& name, const string& revision) {
    stringstream tmp;
    tmp << "ERROR: YANG module " << name << " is not installed." << endl
        << "The environment is not suitable for running unit tests." << endl
        << "Please install the module " << name << ":" << endl
        << "$ sysrepoctl -i ./src/share/yang/modules/" << name << "@" << revision << ".yang" << endl
        << endl;
    return (tmp.str());
}

/// @brief Returns nicely formed error message if module does not have
/// the expected revision.
///
/// @param name name of the YANG module to complain about
/// @param expected expected revision of the YANG module
/// @param got got (bad) revision of the YANG module
string badRevisionModuleText(const string& name, const string& expected,
                             const string& got) {
    stringstream tmp;
    tmp << endl
        << "ERROR: YANG module " << name << " is not installed with the right "
        << "revision: got " << got << ", but expected " << expected << "." << endl
        << "Please remove the module " << name << " and reinstall it: " << endl
        << "$ sysrepoctl -u " << name << endl
        << "$ sysrepoctl -i ./src/share/yang/modules/" << name << "@" << expected << ".yang" << endl
        << endl;
    return (tmp.str());
}

/// @brief Checks sysrepo setup:
///  - connection establishment
///  - session establishment
///  - test module
///  - type modules
///  - IETF module
///  - Kea modules.
///  - daemon required
int main() {
    S_Connection conn;
    try {
        conn = std::make_shared<Connection>();
    } catch (const sysrepo_exception& ex) {
        cerr << "ERROR: Can't initialize sysrepo: " << ex.what() << endl;
        cerr << "ERROR: Make sure you have the right permissions to the sysrepo repository." << endl;
        return (1);
    }

    S_Session sess;
    try {
        sess.reset(new Session(conn, SR_DS_CANDIDATE));
    } catch (const sysrepo_exception& ex) {
        cerr << "ERROR: Can't establish a sysrepo session: "
             << ex.what() << endl;
        return (2);
    }

    vector<S_Module> modules;
    try {
        S_Context context(sess->get_context());
        modules = context->get_module_iter();
    } catch (const sysrepo_exception& ex) {
        cerr << "ERROR: Can't retrieve available modules: " << ex.what() << endl;
        return (3);
    }

    std::unordered_map<std::string, std::string> installed_modules;
    for (S_Module const& module : modules) {
        if (!module->name()) {
            cerr << "ERROR: module name is mangled" << endl;
            return (4);
        }
        string const name(module->name());
        if (!module->rev() || !module->rev()->date()) {
            cerr << "ERROR: module revision is mangled" << endl;
            return (5);
        }
        string const revision(module->rev()->date());
        installed_modules.emplace(name, revision);
    }

    for (auto const& kv : YANG_REVISIONS) {
        std::string const& name(kv.first);
        std::string const& expected_revision(kv.second);
        if (!installed_modules.count(name)) {
            cerr << missingModuleText(name, expected_revision);
            return (6);
        }
        string const& revision(installed_modules.at(name));
        if (expected_revision != revision) {
            cerr << badRevisionModuleText(name, expected_revision, revision);
            return (7);
        }
    }

    return 0;
}