blob: a1d70a445673b3b29be26613df1c23da4b8c28f6 [file]
// Copyright 2020 Google LLC
//
// 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
//
// https://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 "iree/base/dynamic_library.h"
#include <string>
#include "iree/base/dynamic_library_test_library_embed.h"
#include "iree/base/file_io.h"
#include "iree/base/status.h"
#include "iree/base/status_matchers.h"
#include "iree/base/target_platform.h"
#include "iree/testing/gtest.h"
namespace iree {
namespace {
static const char* kUnknownName = "library_that_does_not_exist.so";
class DynamicLibraryTest : public ::testing::Test {
public:
static void SetUpTestCase() {
// Making files available to tests, particularly across operating systems
// and build tools (Bazel/CMake) is complicated. Rather than include a test
// dynamic library as a "testdata" file, we use cc_embed_data to package
// the file so it's embedded in a C++ module, then write that embedded file
// to a platform/test-environment specific temp file for loading.
std::string base_name = "dynamic_library_test_library";
ASSERT_OK_AND_ASSIGN(library_temp_path_, file_io::GetTempFile(base_name));
// System APIs for loading dynamic libraries typically require an extension.
#if defined(IREE_PLATFORM_WINDOWS)
library_temp_path_ += ".dll";
#else
library_temp_path_ += ".so";
#endif
const auto* file_toc = dynamic_library_test_library_create();
absl::string_view file_data(reinterpret_cast<const char*>(file_toc->data),
file_toc->size);
ASSERT_OK(file_io::SetFileContents(library_temp_path_, file_data));
LOG(INFO) << "Embedded test library written to temp path: "
<< library_temp_path_;
}
static std::string library_temp_path_;
};
std::string DynamicLibraryTest::library_temp_path_;
TEST_F(DynamicLibraryTest, LoadLibrarySuccess) {
auto library_or = DynamicLibrary::Load(library_temp_path_.c_str());
ASSERT_OK(library_or);
auto library = std::move(library_or.value());
EXPECT_EQ(library_temp_path_, library->file_name());
}
TEST_F(DynamicLibraryTest, LoadLibraryFailure) {
auto library_or = DynamicLibrary::Load(kUnknownName);
EXPECT_TRUE(IsUnavailable(library_or.status()));
}
TEST_F(DynamicLibraryTest, LoadLibraryTwice) {
ASSERT_OK_AND_ASSIGN(auto library1,
DynamicLibrary::Load(library_temp_path_.c_str()));
ASSERT_OK_AND_ASSIGN(auto library2,
DynamicLibrary::Load(library_temp_path_.c_str()));
}
TEST_F(DynamicLibraryTest, GetSymbolSuccess) {
ASSERT_OK_AND_ASSIGN(auto library,
DynamicLibrary::Load(library_temp_path_.c_str()));
auto times_two_fn = library->GetSymbol<int (*)(int)>("times_two");
ASSERT_NE(nullptr, times_two_fn);
EXPECT_EQ(246, times_two_fn(123));
}
TEST_F(DynamicLibraryTest, GetSymbolFailure) {
ASSERT_OK_AND_ASSIGN(auto library,
DynamicLibrary::Load(library_temp_path_.c_str()));
auto unknown_fn = library->GetSymbol<int (*)(int)>("unknown");
EXPECT_EQ(nullptr, unknown_fn);
}
} // namespace
} // namespace iree