blob: b9c757842933e134bd401f11730887ccbc718c2a [file]
// Copyright 2023 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 "mpact/sim/generic/simple_resource.h"
#include <memory>
#include "googlemock/include/gmock/gmock.h"
#include "googletest/include/gtest/gtest.h"
using testing::StrEq;
namespace mpact {
namespace sim {
namespace generic {
namespace {
// Will run the test on a single resource pool, with three resource instances.
static constexpr char kTestPoolName[] = "TestPool";
static constexpr int kTestPoolSize = 35;
static constexpr int kNumResources = 3;
static constexpr char kTestResource0[] = "Resource0";
static constexpr char kTestResource1[] = "Resource1";
static constexpr char kTestResource2[] = "Resource2";
static constexpr char const *kTestResources[] = {kTestResource0, kTestResource1,
kTestResource2};
class SimpleResourceTest : public testing::Test {
protected:
SimpleResourceTest() {
pool_ = std::make_unique<SimpleResourcePool>(kTestPoolName, kTestPoolSize);
}
~SimpleResourceTest() override {}
std::unique_ptr<SimpleResourcePool> pool_;
};
TEST_F(SimpleResourceTest, Instantiation) {
EXPECT_THAT(pool_->name(), StrEq(kTestPoolName));
EXPECT_EQ(pool_->width(), kTestPoolSize);
EXPECT_EQ(pool_->resource_vector().GetOnesCount(), 0);
}
TEST_F(SimpleResourceTest, Resources) {
SimpleResource *resources[kNumResources];
for (int num = 0; num < kNumResources; num++) {
const char *name = kTestResources[num];
// Creat resource.
EXPECT_TRUE(pool_->AddResource(name).ok());
resources[num] = pool_->GetResource(name);
EXPECT_THAT(resources[num]->name(), StrEq(name));
// Verify resource properties.
EXPECT_EQ(resources[num]->index(), num);
EXPECT_EQ(resources[num]->resource_bit().GetOnesCount(), 1);
int position;
EXPECT_TRUE(resources[num]->resource_bit().FindFirstSetBit(&position));
EXPECT_EQ(position, num);
// Try reserving resource and free it.
EXPECT_TRUE(resources[num]->IsFree());
resources[num]->Acquire();
EXPECT_EQ(pool_->resource_vector().GetOnesCount(), 1);
EXPECT_TRUE(resources[num]->resource_bit().FindFirstSetBit(&position));
EXPECT_EQ(position, num);
EXPECT_FALSE(resources[num]->IsFree());
resources[num]->Release();
EXPECT_EQ(pool_->resource_vector().GetOnesCount(), 0);
}
for (int num = 0; num < kNumResources; num++) {
resources[num]->Acquire();
EXPECT_EQ(pool_->resource_vector().GetOnesCount(), num + 1);
}
}
TEST_F(SimpleResourceTest, ResourceSets) {
SimpleResource *resources[kNumResources];
for (int num = 0; num < kNumResources; num++) {
const char *name = kTestResources[num];
// Creat resource.
EXPECT_TRUE(pool_->AddResource(name).ok());
resources[num] = pool_->GetResource(name);
}
// Create a resource set and add resource 0 and 1 to it.
SimpleResourceSet *resource_set = pool_->CreateResourceSet();
EXPECT_TRUE(resource_set->AddResource(kTestResource0).ok());
EXPECT_TRUE(resource_set->AddResource(resources[1]).ok());
// Acquire resource 2.
resources[2]->Acquire();
EXPECT_TRUE(resource_set->IsFree());
// Acquire resource 1.
resources[1]->Acquire();
EXPECT_FALSE(resource_set->IsFree());
// Release resource 1.
resources[1]->Release();
// Acquire the resource set.
resource_set->Acquire();
// All resources should now be reserved.
EXPECT_EQ(pool_->resource_vector().GetOnesCount(), 3);
EXPECT_FALSE(resources[0]->IsFree());
EXPECT_FALSE(resources[1]->IsFree());
EXPECT_FALSE(resources[2]->IsFree());
// Release the resource set. Resource 2 should still be reserved.
resource_set->Release();
EXPECT_EQ(pool_->resource_vector().GetOnesCount(), 1);
EXPECT_TRUE(resources[0]->IsFree());
EXPECT_TRUE(resources[1]->IsFree());
EXPECT_FALSE(resources[2]->IsFree());
EXPECT_TRUE(resource_set->IsFree());
}
} // namespace
} // namespace generic
} // namespace sim
} // namespace mpact