blob: 85f1694be4498b9902f7af1a62ed93c0f9a45d02 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "magma.h"
#include "mock/mock_msd.h"
#include "sys_driver/magma_system_connection.h"
#include "sys_driver/magma_system_device.h"
#include "gtest/gtest.h"
class MsdMockDevice_GetDeviceId : public MsdMockDevice {
public:
MsdMockDevice_GetDeviceId(uint32_t device_id) : device_id_(device_id) {}
uint32_t GetDeviceId() override { return device_id_; }
private:
uint32_t device_id_;
};
TEST(MagmaSystemConnection, GetDeviceId)
{
uint32_t test_id = 0xdeadbeef;
auto msd_dev = new MsdMockDevice_GetDeviceId(test_id);
auto device = MagmaSystemDevice::Create(MsdDeviceUniquePtr(msd_dev));
uint32_t device_id = device->GetDeviceId();
// For now device_id is invalid
EXPECT_EQ(device_id, test_id);
}
class MsdMockConnection_ContextManagement : public MsdMockConnection {
public:
MsdMockConnection_ContextManagement() {}
MsdMockContext* CreateContext() override
{
active_context_count_++;
return MsdMockConnection::CreateContext();
}
void DestroyContext(MsdMockContext* ctx) override
{
active_context_count_--;
MsdMockConnection::DestroyContext(ctx);
}
uint32_t NumActiveContexts() { return active_context_count_; }
private:
uint32_t active_context_count_ = 0;
};
TEST(MagmaSystemConnection, ContextManagement)
{
auto msd_connection = new MsdMockConnection_ContextManagement();
auto msd_dev = new MsdMockDevice();
auto dev =
std::shared_ptr<MagmaSystemDevice>(MagmaSystemDevice::Create(MsdDeviceUniquePtr(msd_dev)));
MagmaSystemConnection connection(dev, MsdConnectionUniquePtr(msd_connection));
EXPECT_EQ(msd_connection->NumActiveContexts(), 0u);
uint32_t context_id_0 = 0;
uint32_t context_id_1 = 1;
EXPECT_TRUE(connection.CreateContext(context_id_0));
EXPECT_EQ(msd_connection->NumActiveContexts(), 1u);
EXPECT_TRUE(connection.CreateContext(context_id_1));
EXPECT_EQ(msd_connection->NumActiveContexts(), 2u);
EXPECT_TRUE(connection.DestroyContext(context_id_0));
EXPECT_EQ(msd_connection->NumActiveContexts(), 1u);
EXPECT_FALSE(connection.DestroyContext(context_id_0));
EXPECT_TRUE(connection.DestroyContext(context_id_1));
EXPECT_EQ(msd_connection->NumActiveContexts(), 0u);
EXPECT_FALSE(connection.DestroyContext(context_id_1));
}
TEST(MagmaSystemConnection, BufferManagement)
{
auto msd_drv = msd_driver_create();
ASSERT_NE(msd_drv, nullptr);
auto msd_dev = msd_driver_create_device(msd_drv, nullptr);
ASSERT_NE(msd_dev, nullptr);
auto dev =
std::shared_ptr<MagmaSystemDevice>(MagmaSystemDevice::Create(MsdDeviceUniquePtr(msd_dev)));
auto msd_connection = msd_device_open(msd_dev, 0);
ASSERT_NE(msd_connection, nullptr);
MagmaSystemConnection connection(dev, MsdConnectionUniquePtr(msd_connection));
uint64_t test_size = 4096;
auto buf = magma::PlatformBuffer::Create(test_size, "test");
// assert because if this fails the rest of this is gonna be bogus anyway
ASSERT_NE(buf, nullptr);
EXPECT_GE(buf->size(), test_size);
uint32_t duplicate_handle1;
ASSERT_TRUE(buf->duplicate_handle(&duplicate_handle1));
uint64_t id;
EXPECT_TRUE(connection.ImportBuffer(duplicate_handle1, &id));
// should be able to get the buffer by handle
auto get_buf = connection.LookupBuffer(id);
EXPECT_NE(get_buf, nullptr);
EXPECT_EQ(get_buf->id(), id); // they are shared ptrs after all
uint32_t duplicate_handle2;
ASSERT_TRUE(buf->duplicate_handle(&duplicate_handle2));
EXPECT_TRUE(connection.ImportBuffer(duplicate_handle2, &id));
// freeing the allocated buffer should cause refcount to drop to 1
EXPECT_TRUE(connection.ReleaseBuffer(id));
EXPECT_NE(connection.LookupBuffer(id), nullptr);
// freeing the allocated buffer should work
EXPECT_TRUE(connection.ReleaseBuffer(id));
// should no longer be able to get it from the map
EXPECT_EQ(connection.LookupBuffer(id), nullptr);
// should not be able to double free it
EXPECT_FALSE(connection.ReleaseBuffer(id));
}
TEST(MagmaSystemConnection, Semaphores)
{
auto msd_drv = msd_driver_create();
ASSERT_NE(msd_drv, nullptr);
auto msd_dev = msd_driver_create_device(msd_drv, nullptr);
ASSERT_NE(msd_dev, nullptr);
auto dev =
std::shared_ptr<MagmaSystemDevice>(MagmaSystemDevice::Create(MsdDeviceUniquePtr(msd_dev)));
auto msd_connection = msd_device_open(msd_dev, 0);
ASSERT_NE(msd_connection, nullptr);
MagmaSystemConnection connection(dev, MsdConnectionUniquePtr(msd_connection));
auto semaphore = magma::PlatformSemaphore::Create();
// assert because if this fails the rest of this is gonna be bogus anyway
ASSERT_NE(semaphore, nullptr);
uint32_t duplicate_handle1;
ASSERT_TRUE(semaphore->duplicate_handle(&duplicate_handle1));
EXPECT_TRUE(connection.ImportObject(duplicate_handle1, magma::PlatformObject::SEMAPHORE));
auto system_semaphore = connection.LookupSemaphore(semaphore->id());
EXPECT_NE(system_semaphore, nullptr);
EXPECT_EQ(system_semaphore->platform_semaphore()->id(), semaphore->id());
uint32_t duplicate_handle2;
ASSERT_TRUE(semaphore->duplicate_handle(&duplicate_handle2));
EXPECT_TRUE(connection.ImportObject(duplicate_handle2, magma::PlatformObject::SEMAPHORE));
// freeing the allocated semaphore should decrease refcount to 1
EXPECT_TRUE(connection.ReleaseObject(semaphore->id(), magma::PlatformObject::SEMAPHORE));
EXPECT_NE(connection.LookupSemaphore(semaphore->id()), nullptr);
// freeing the allocated buffer should work
EXPECT_TRUE(connection.ReleaseObject(semaphore->id(), magma::PlatformObject::SEMAPHORE));
// should no longer be able to get it from the map
EXPECT_EQ(connection.LookupSemaphore(semaphore->id()), nullptr);
// should not be able to double free it
EXPECT_FALSE(connection.ReleaseObject(semaphore->id(), magma::PlatformObject::SEMAPHORE));
}
TEST(MagmaSystemConnection, BufferSharing)
{
auto msd_drv = msd_driver_create();
ASSERT_NE(msd_drv, nullptr);
auto msd_dev = msd_driver_create_device(msd_drv, nullptr);
ASSERT_NE(msd_dev, nullptr);
auto dev =
std::shared_ptr<MagmaSystemDevice>(MagmaSystemDevice::Create(MsdDeviceUniquePtr(msd_dev)));
auto msd_connection = msd_device_open(msd_dev, 0);
ASSERT_NE(msd_connection, nullptr);
MagmaSystemConnection connection_0(dev, MsdConnectionUniquePtr(msd_connection));
msd_connection = msd_device_open(msd_dev, 0);
ASSERT_NE(msd_connection, nullptr);
MagmaSystemConnection connection_1(dev, MsdConnectionUniquePtr(msd_connection));
auto platform_buf = magma::PlatformBuffer::Create(4096, "test");
uint64_t buf_id_0 = 0;
uint64_t buf_id_1 = 1;
uint32_t duplicate_handle;
ASSERT_TRUE(platform_buf->duplicate_handle(&duplicate_handle));
EXPECT_TRUE(connection_0.ImportBuffer(duplicate_handle, &buf_id_0));
ASSERT_TRUE(platform_buf->duplicate_handle(&duplicate_handle));
EXPECT_TRUE(connection_1.ImportBuffer(duplicate_handle, &buf_id_1));
// should be the same underlying memory object
EXPECT_EQ(buf_id_0, buf_id_1);
auto buf_0 = connection_0.LookupBuffer(buf_id_0);
auto buf_1 = connection_1.LookupBuffer(buf_id_1);
EXPECT_EQ(buf_0->id(), buf_1->id());
}