blob: ee71ff4e53026bbc41f06f99504dd964581fe68a [file] [log] [blame]
Tomáš Pecka5c19e722021-02-15 20:41:29 +01001/*
2 * Copyright (C) 2021 CESNET, https://photonics.cesnet.cz/
3 *
4 * Written by Tomáš Pecka <tomas.pecka@cesnet.cz>
5 *
6*/
7
8#include "trompeloeil_doctest.h"
9#include <filesystem>
10#include "fs-helpers/utils.h"
11#include "pretty_printers.h"
12#include "system/Network.h"
13#include "test_log_setup.h"
14#include "test_sysrepo_helpers.h"
15#include "tests/configure.cmake.h"
16#include "utils/io.h"
17
18using namespace std::string_literals;
19using namespace std::chrono_literals;
20
21struct FakeNetworkReload {
22public:
23 MAKE_CONST_MOCK1(cb, void(const std::vector<std::string>&));
24};
25
26TEST_CASE("Standalone eth1")
27{
28 const auto PRESENCE_CONTAINER = "/czechlight-system:networking/standalone-eth1";
29
30 static const std::string EXPECTED_CONTENT_BRIDGE = R"([Match]
31Name=eth1
32
33[Network]
34Bridge=br0
35LLDP=true
36EmitLLDP=nearest-bridge
37)";
38
39 static const std::string EXPECTED_CONTENT_DHCP = R"([Match]
40Name=eth1
41
42[Network]
43DHCP=yes
44LLDP=true
45EmitLLDP=nearest-bridge
46)";
47
48 TEST_SYSREPO_INIT_LOGS;
49 TEST_SYSREPO_INIT;
50 TEST_SYSREPO_INIT_CLIENT;
Tomáš Peckaa936ee72021-02-15 21:37:10 +010051
Tomáš Pecka5c19e722021-02-15 20:41:29 +010052 trompeloeil::sequence seq1;
53 std::string expectedContent;
54 auto fake = FakeNetworkReload();
55 auto fakeDir = std::filesystem::path(CMAKE_CURRENT_BINARY_DIR) / "tests/network/"s;
56 auto expectedFilePath = fakeDir / "eth1.network"s;
57
58 // reset
59 removeDirectoryTreeIfExists(fakeDir);
60 std::filesystem::create_directories(fakeDir);
61
Tomáš Peckaa936ee72021-02-15 21:37:10 +010062 SECTION("Running DS")
Tomáš Pecka5c19e722021-02-15 20:41:29 +010063 {
Tomáš Peckaa936ee72021-02-15 21:37:10 +010064 SECTION("Container not present. Start with bridge configuration")
Tomáš Pecka5c19e722021-02-15 20:41:29 +010065 {
Tomáš Peckaa936ee72021-02-15 21:37:10 +010066 client->delete_item(PRESENCE_CONTAINER);
67 client->apply_changes();
68
69 REQUIRE_CALL(fake, cb(std::vector<std::string> {"eth1"})).IN_SEQUENCE(seq1);
70 auto network = std::make_shared<velia::system::Network>(srSess, fakeDir, [&fake](const std::vector<std::string>& updatedInterfaces) { fake.cb(updatedInterfaces); });
71
72 REQUIRE(std::filesystem::exists(expectedFilePath));
73 REQUIRE(velia::utils::readFileToString(expectedFilePath) == EXPECTED_CONTENT_BRIDGE);
74
75 SECTION("Nothing happens")
76 {
77 }
78
79 SECTION("Change: Container present. Switch to DHCP configuration")
80 {
81 REQUIRE_CALL(fake, cb(std::vector<std::string> {"eth1"})).IN_SEQUENCE(seq1);
82
83 client->set_item(PRESENCE_CONTAINER);
84 client->apply_changes();
85 waitForCompletionAndBitMore(seq1);
86
87 REQUIRE(std::filesystem::exists(expectedFilePath));
88 REQUIRE(velia::utils::readFileToString(expectedFilePath) == EXPECTED_CONTENT_DHCP);
89 }
Tomáš Pecka5c19e722021-02-15 20:41:29 +010090
91 }
92
Tomáš Peckaa936ee72021-02-15 21:37:10 +010093 SECTION("Container present. Start with DHCP configuration")
Tomáš Pecka5c19e722021-02-15 20:41:29 +010094 {
Tomáš Peckaa936ee72021-02-15 21:37:10 +010095 client->set_item(PRESENCE_CONTAINER);
96 client->apply_changes();
Tomáš Pecka5c19e722021-02-15 20:41:29 +010097
Tomáš Peckaa936ee72021-02-15 21:37:10 +010098 REQUIRE_CALL(fake, cb(std::vector<std::string> {"eth1"})).IN_SEQUENCE(seq1);
99 auto network = std::make_shared<velia::system::Network>(srSess, fakeDir, [&fake](const std::vector<std::string>& updatedInterfaces) { fake.cb(updatedInterfaces); });
100
101 REQUIRE(std::filesystem::exists(expectedFilePath));
102 REQUIRE(velia::utils::readFileToString(expectedFilePath) == EXPECTED_CONTENT_DHCP);
103
104 SECTION("Nothing happens")
105 {
106 }
107
108 SECTION("Change: Container not present. Switch to bridge configuration")
109 {
110 REQUIRE_CALL(fake, cb(std::vector<std::string> {"eth1"})).IN_SEQUENCE(seq1);
111
112 client->delete_item(PRESENCE_CONTAINER);
113 client->apply_changes();
114 waitForCompletionAndBitMore(seq1);
115
116 REQUIRE(std::filesystem::exists(expectedFilePath));
117 REQUIRE(velia::utils::readFileToString(expectedFilePath) == EXPECTED_CONTENT_BRIDGE);
118 }
119 }
120 }
121
122 SECTION("Startup DS")
123 {
124 srSess->session_switch_ds(SR_DS_STARTUP);
125 client->session_switch_ds(SR_DS_STARTUP);
126
127 auto network = std::make_shared<velia::system::Network>(srSess, fakeDir, []([[maybe_unused]] const std::vector<std::string>& updatedInterfaces) {});
128
129 SECTION("Change in startup datastore: Persist DHCP configuration")
130 {
Tomáš Pecka5c19e722021-02-15 20:41:29 +0100131 client->set_item(PRESENCE_CONTAINER);
132 client->apply_changes();
133
134 REQUIRE(std::filesystem::exists(expectedFilePath));
135 REQUIRE(velia::utils::readFileToString(expectedFilePath) == EXPECTED_CONTENT_DHCP);
136 }
Tomáš Pecka5c19e722021-02-15 20:41:29 +0100137
Tomáš Peckaa936ee72021-02-15 21:37:10 +0100138 SECTION("Change in startup datastore: Persist bridge configuration")
Tomáš Pecka5c19e722021-02-15 20:41:29 +0100139 {
Tomáš Pecka5c19e722021-02-15 20:41:29 +0100140 client->delete_item(PRESENCE_CONTAINER);
141 client->apply_changes();
142
143 REQUIRE(std::filesystem::exists(expectedFilePath));
144 REQUIRE(velia::utils::readFileToString(expectedFilePath) == EXPECTED_CONTENT_BRIDGE);
145 }
146 }
147}