Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Thinkit] Added GenericTestbed and ControlInterface interfaces. #357

Merged
merged 3 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions thinkit/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,26 @@ package(
cc_library(
name = "thinkit",
deps = [
":control_interface",
":generic_testbed",
":mirror_testbed",
":switch",
":test_environment",
],
)

cc_library(
name = "thinkit_mocks",
testonly = 1,
deps = [
":mock_control_interface",
":mock_generic_testbed",
":mock_mirror_testbed",
":mock_switch",
":mock_test_environment",
],
)

cc_library(
name = "switch",
hdrs = ["switch.h"],
Expand Down Expand Up @@ -205,6 +219,55 @@ cc_test(
],
)

cc_library(
name = "generic_testbed",
hdrs = ["generic_testbed.h"],
deps = [
":control_interface",
":switch",
":test_environment",
"//thinkit/proto:generic_testbed_cc_proto",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
],
)

cc_library(
name = "generic_testbed_fixture",
testonly = 1,
hdrs = ["generic_testbed_fixture.h"],
deps = [
":generic_testbed",
"@com_google_absl//absl/memory",
"@com_google_googletest//:gtest",
],
)

cc_library(
name = "mock_generic_testbed",
testonly = 1,
hdrs = ["mock_generic_testbed.h"],
deps = [
":control_interface",
":generic_testbed",
":switch",
":test_environment",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
"@com_google_googletest//:gtest",
],
)

cc_test(
name = "mock_generic_testbed_test",
srcs = ["mock_generic_testbed_test.cc"],
deps = [
":mock_generic_testbed",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "control_interface",
hdrs = ["control_interface.h"],
Expand All @@ -217,6 +280,28 @@ cc_library(
],
)

cc_library(
name = "mock_control_interface",
testonly = 1,
hdrs = ["mock_control_interface.h"],
deps = [
":control_interface",
"@com_github_gnoi//diag:diag_cc_grpc_proto",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/status:statusor",
"@com_google_googletest//:gtest",
],
)

cc_test(
name = "mock_control_interface_test",
srcs = ["mock_control_interface_test.cc"],
deps = [
":mock_control_interface",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "packet_generation_finalizer",
hdrs = ["packet_generation_finalizer.h"],
Expand Down
3 changes: 2 additions & 1 deletion thinkit/bazel_test_environment.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ class BazelTestEnvironment : public TestEnvironment {

absl::Status StoreTestArtifact(absl::string_view filename,
absl::string_view contents) override;
using TestEnvironment::StoreTestArtifact; // Inherit protobuf overload.

absl::Status AppendToTestArtifact(absl::string_view filename,
absl::string_view contents) override;

using TestEnvironment::AppendToTestArtifact; // Inherit protobuf overload.

bool MaskKnownFailures() { return mask_known_failures_; };

Expand Down
76 changes: 76 additions & 0 deletions thinkit/generic_testbed.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright (c) 2024, Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef GOOGLE_THINKIT_GENERIC_TESTBED_H_
#define GOOGLE_THINKIT_GENERIC_TESTBED_H_

#include <string>

#include "absl/container/flat_hash_map.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "thinkit/control_interface.h"
#include "thinkit/proto/generic_testbed.pb.h"
#include "thinkit/switch.h"
#include "thinkit/test_environment.h"

namespace thinkit {

// HttpResponse represents an HTTP response from an Ixia device.
struct HttpResponse {
int response_code;
std::string response;
};

enum class RequestType {
kGet,
kPost,
kPut,
kDelete,
};

// InterfaceInfo represents the mode of an interface and the name of the peer
// interface.
struct InterfaceInfo {
third_party::pins_infra::thinkit::InterfaceMode interface_mode;
std::string peer_interface_name; // Empty if not applicable.
};

// The GenericTestbed interface represents a testbed with control interface and
// Ixia interface.
class GenericTestbed {
public:
virtual ~GenericTestbed() {}

// Returns the switch (aka system) under test.
virtual Switch& Sut() = 0;

// Returns the control interface responsible for packet injection and various
// management operations.
virtual ControlInterface& Interface() = 0;

// Returns the test environment in which the test is run.
virtual TestEnvironment& Environment() = 0;

// Returns the information for all SUT interfaces.
virtual absl::flat_hash_map<std::string, InterfaceInfo>
GetSutInterfaceInfo() = 0;

// Sends a REST request to the Ixia and returns the response.
virtual absl::StatusOr<HttpResponse> SendRestRequestToIxia(
RequestType type, absl::string_view url, absl::string_view payload) = 0;
};

} // namespace thinkit
#endif // GOOGLE_THINKIT_GENERIC_TESTBED_H_
101 changes: 101 additions & 0 deletions thinkit/generic_testbed_fixture.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright (c) 2024, Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef GOOGLE_THINKIT_GENERIC_TESTBED_TEST_FIXTURE_H_
#define GOOGLE_THINKIT_GENERIC_TESTBED_TEST_FIXTURE_H_

#include <memory>

#include "absl/memory/memory.h"
#include "gtest/gtest.h"
#include "thinkit/generic_testbed.h"

namespace thinkit {

// The ThinKit `GenericTestbedInterface` defines an interface every test
// platform should implement. The expectations are such that the GenericTestbed
// should only be accessed after SetUp() is called and before TearDown() is
// called.
class GenericTestbedInterface {
public:
virtual ~GenericTestbedInterface() = default;

virtual void SetUp() = 0;
virtual void TearDown() = 0;

virtual GenericTestbed& GetGenericTestbed() = 0;
};

// The Thinkit `TestParams` defines test parameters to
// `GenericTestbedFixture` class.
struct TestParams {
// Ownership transferred in GenericTestbedFixture class.
GenericTestbedInterface* generic_testbed;
std::string gnmi_config;
absl::optional<std::vector<int>> port_ids;
};

// The ThinKit `GenericTestbedFixture` class acts as a base test fixture for
// platform independent PINS tests. Any platform specific SetUp or TearDown
// requirements are abstracted through the ThinKit GenericTestbedInterface which
// is passed as a parameter.
//
// New PINS tests should extend this fixture, and if needed can extend the
// SetUp() and/or TearDown() methods:
// class MyPinsTest : public thinkit::GenericTestbedFixture {
// void SetUp() override {
// GenericTestbedFixture::SetUp(); // called first.
//
// // custom setup steps ...
// }
//
// void TearDown() override {
// // custom tear down steps ...
//
// GenericTestbedFixture::TearDown(); // called last.
// }
// };
//
// Individual tests should use the new suite name:
// TEST_P(MyPinsTest, MyTestName) {}
class GenericTestbedFixture : public testing::TestWithParam<TestParams> {
protected:
// A derived class that needs/wants to do its own setup can override this
// method. However, it should take care to call this base setup first. That
// will ensure the platform is ready, and in a healthy state.
void SetUp() override { generic_testbed_interface_->SetUp(); }

// A derived class that needs/wants to do its own teardown can override this
// method. However, it should take care to call this base teardown last. Once
// this method is called accessing the platform can result in unexpected
// behaviors.
void TearDown() override { generic_testbed_interface_->TearDown(); }

// Accessor for the Generic testbed. This is only safe to be called after the
// SetUp has completed.
GenericTestbed& GetGenericTestbed() {
return generic_testbed_interface_->GetGenericTestbed();
}

std::string GetGnmiConfig() { return GetParam().gnmi_config; }

private:
// Takes ownership of the GenericTestbedInterface parameter.
std::unique_ptr<GenericTestbedInterface> generic_testbed_interface_ =
absl::WrapUnique<GenericTestbedInterface>(GetParam().generic_testbed);
};

} // namespace thinkit

#endif // GOOGLE_THINKIT_GENERIC_TESTBED_TEST_FIXTURE_H_
44 changes: 44 additions & 0 deletions thinkit/mock_control_interface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2024, Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef GOOGLE_THINKIT_MOCK_CONTROL_INTERFACE_H_
#define GOOGLE_THINKIT_MOCK_CONTROL_INTERFACE_H_

#include "absl/container/flat_hash_set.h"
#include "absl/status/statusor.h"
#include "diag/diag.grpc.pb.h"
#include "gmock/gmock.h"
#include "thinkit/control_interface.h"

namespace thinkit {
class MockControlInterface : public ControlInterface {
public:
MOCK_METHOD(absl::Status, SetAdminLinkState,
(absl::Span<const std::string> sut_ports, LinkState state),
(override));
MOCK_METHOD(absl::Status, Reboot, (RebootType reboot_Type), (override));
MOCK_METHOD(absl::StatusOr<gnoi::diag::StartBERTResponse>, StartBERT,
(const gnoi::diag::StartBERTRequest& request), (override));
MOCK_METHOD(absl::StatusOr<gnoi::diag::StopBERTResponse>, StopBERT,
(const gnoi::diag::StopBERTRequest& request), (override));
MOCK_METHOD(absl::StatusOr<gnoi::diag::GetBERTResultResponse>, GetBERTResult,
(const gnoi::diag::GetBERTResultRequest& request));
MOCK_METHOD(absl::StatusOr<absl::flat_hash_set<std::string>>, GetUpLinks,
(absl::Span<const std::string> sut_ports), (override));
MOCK_METHOD(absl::Status, CheckUp, (), (override));
};

} // namespace thinkit

#endif // GOOGLE_THINKIT_MOCK_CONTROL_INTERFACE_H_
25 changes: 25 additions & 0 deletions thinkit/mock_control_interface_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) 2024, Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "thinkit/mock_control_interface.h"

#include "gtest/gtest.h"

namespace thinkit {
namespace {

TEST(MockControlInterface, TestBuild) { MockControlInterface mock; }

} // namespace
} // namespace thinkit
Loading
Loading