test: Strengthen C++ test assertions with meaningful checks

Replace empty-body checks and trivial file-existence assertions with
actual content verification and state validation in C++ unit tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
This commit is contained in:
Jaehyun Kim 2026-02-22 18:50:18 +09:00
parent e5d8d8c970
commit 0693e7d479
3 changed files with 84 additions and 27 deletions

View File

@ -1,5 +1,8 @@
#include <gtest/gtest.h>
#include <tcl.h>
#include <fstream>
#include <iterator>
#include <string>
#include "Transition.hh"
#include "MinMax.hh"
#include "ExceptionPath.hh"
@ -32,6 +35,16 @@
namespace sta {
static std::string
readTextFile(const char *filename)
{
std::ifstream in(filename);
if (!in.is_open())
return "";
return std::string((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
}
// RiseFall tests
class RiseFallTest : public ::testing::Test {};
@ -10215,9 +10228,10 @@ TEST_F(SdcDesignTest, WriteSdcLatchBorrowClock) {
}
const char *filename = "/tmp/test_sdc_r11_latchborrowclk.sdc";
sta_->writeSdc(filename, false, false, 4, false, true);
FILE *f = fopen(filename, "r");
EXPECT_NE(f, nullptr);
if (f) fclose(f);
std::string text = readTextFile(filename);
ASSERT_FALSE(text.empty());
EXPECT_NE(text.find("set_max_time_borrow"), std::string::npos);
EXPECT_NE(text.find("[get_clocks {clk}]"), std::string::npos);
}
// --- WriteSdc with derating on cell, instance, net ---
@ -10259,9 +10273,14 @@ TEST_F(SdcDesignTest, WriteSdcDeratingCellInstNet) {
const char *filename = "/tmp/test_sdc_r11_derate_all.sdc";
sta_->writeSdc(filename, false, false, 4, false, true);
FILE *f = fopen(filename, "r");
EXPECT_NE(f, nullptr);
if (f) fclose(f);
std::string text = readTextFile(filename);
ASSERT_FALSE(text.empty());
EXPECT_NE(text.find("set_timing_derate -net_delay -early -data"),
std::string::npos);
EXPECT_NE(text.find("set_timing_derate -cell_delay -late -data"),
std::string::npos);
EXPECT_NE(text.find("set_timing_derate -cell_delay -early -data"),
std::string::npos);
}
// --- Sdc: capacitanceLimit on pin ---
@ -10286,9 +10305,9 @@ TEST_F(SdcDesignTest, WriteSdcFalsePathHold) {
sta_->makeFalsePath(nullptr, nullptr, nullptr, MinMaxAll::min(), nullptr);
const char *filename = "/tmp/test_sdc_r11_fp_hold.sdc";
sta_->writeSdc(filename, false, false, 4, false, true);
FILE *f = fopen(filename, "r");
EXPECT_NE(f, nullptr);
if (f) fclose(f);
std::string text = readTextFile(filename);
ASSERT_FALSE(text.empty());
EXPECT_NE(text.find("set_false_path -hold"), std::string::npos);
}
// --- WriteSdc with set_false_path -setup only
@ -10297,9 +10316,9 @@ TEST_F(SdcDesignTest, WriteSdcFalsePathSetup) {
sta_->makeFalsePath(nullptr, nullptr, nullptr, MinMaxAll::max(), nullptr);
const char *filename = "/tmp/test_sdc_r11_fp_setup.sdc";
sta_->writeSdc(filename, false, false, 4, false, true);
FILE *f = fopen(filename, "r");
EXPECT_NE(f, nullptr);
if (f) fclose(f);
std::string text = readTextFile(filename);
ASSERT_FALSE(text.empty());
EXPECT_NE(text.find("set_false_path -setup"), std::string::npos);
}
// --- WriteSdc with exception -through with rise_through
@ -10319,9 +10338,10 @@ TEST_F(SdcDesignTest, WriteSdcFalsePathRiseThru) {
}
const char *filename = "/tmp/test_sdc_r11_fp_risethru.sdc";
sta_->writeSdc(filename, false, false, 4, false, true);
FILE *f = fopen(filename, "r");
EXPECT_NE(f, nullptr);
if (f) fclose(f);
std::string text = readTextFile(filename);
ASSERT_FALSE(text.empty());
EXPECT_NE(text.find("set_false_path"), std::string::npos);
EXPECT_NE(text.find("-rise_through [get_ports {in1}]"), std::string::npos);
}
} // namespace sta

View File

@ -1965,8 +1965,14 @@ TEST_F(StaInitTest, WorstSlackNoDesign) {
}
TEST_F(StaInitTest, ClearNoDesign) {
// clear should not crash on empty design
ASSERT_NE(sta_->network(), nullptr);
ASSERT_NE(sta_->sdc(), nullptr);
sta_->clear();
EXPECT_NE(sta_->network(), nullptr);
EXPECT_NE(sta_->sdc(), nullptr);
EXPECT_NE(sta_->search(), nullptr);
EXPECT_EQ(sta_->graph(), nullptr);
EXPECT_NE(sta_->sdc()->defaultArrivalClock(), nullptr);
}
TEST_F(StaInitTest, SdcAnalysisType) {
@ -2111,18 +2117,33 @@ TEST_F(StaInitTest, UseDefaultArrivalClock) {
// Report path format settings - exercise ReportPath.cc
TEST_F(StaInitTest, SetReportPathFormat) {
ReportPath *rpt = sta_->reportPath();
ASSERT_NE(rpt, nullptr);
sta_->setReportPathFormat(ReportPathFormat::full);
EXPECT_EQ(rpt->pathFormat(), ReportPathFormat::full);
sta_->setReportPathFormat(ReportPathFormat::full_clock);
EXPECT_EQ(rpt->pathFormat(), ReportPathFormat::full_clock);
sta_->setReportPathFormat(ReportPathFormat::full_clock_expanded);
EXPECT_EQ(rpt->pathFormat(), ReportPathFormat::full_clock_expanded);
sta_->setReportPathFormat(ReportPathFormat::endpoint);
EXPECT_EQ(rpt->pathFormat(), ReportPathFormat::endpoint);
sta_->setReportPathFormat(ReportPathFormat::summary);
EXPECT_EQ(rpt->pathFormat(), ReportPathFormat::summary);
sta_->setReportPathFormat(ReportPathFormat::slack_only);
EXPECT_EQ(rpt->pathFormat(), ReportPathFormat::slack_only);
sta_->setReportPathFormat(ReportPathFormat::json);
EXPECT_EQ(rpt->pathFormat(), ReportPathFormat::json);
}
TEST_F(StaInitTest, SetReportPathDigits) {
ReportPath *rpt = sta_->reportPath();
ASSERT_NE(rpt, nullptr);
sta_->setReportPathDigits(4);
EXPECT_EQ(rpt->digits(), 4);
sta_->setReportPathDigits(2);
EXPECT_EQ(rpt->digits(), 2);
}
TEST_F(StaInitTest, SetReportPathNoSplit) {
@ -2131,8 +2152,13 @@ TEST_F(StaInitTest, SetReportPathNoSplit) {
}
TEST_F(StaInitTest, SetReportPathSigmas) {
ReportPath *rpt = sta_->reportPath();
ASSERT_NE(rpt, nullptr);
sta_->setReportPathSigmas(true);
EXPECT_TRUE(rpt->reportSigmas());
sta_->setReportPathSigmas(false);
EXPECT_FALSE(rpt->reportSigmas());
}
TEST_F(StaInitTest, SetReportPathFields) {
@ -2179,7 +2205,14 @@ TEST_F(StaInitTest, MakeCorners) {
// SDC operations via Sta
TEST_F(StaInitTest, SdcRemoveConstraints) {
Sdc *sdc = sta_->sdc();
ASSERT_NE(sdc, nullptr);
sdc->setAnalysisType(AnalysisType::bc_wc);
sta_->removeConstraints();
EXPECT_EQ(sdc->analysisType(), AnalysisType::bc_wc);
EXPECT_NE(sdc->defaultArrivalClock(), nullptr);
EXPECT_NE(sdc->defaultArrivalClockEdge(), nullptr);
EXPECT_TRUE(sdc->clks().empty());
}
TEST_F(StaInitTest, SdcConstraintsChanged) {
@ -3062,7 +3095,7 @@ TEST_F(StaInitTest, SearchDeleteFilter) {
TEST_F(StaInitTest, SearchDeletePathGroups) {
Search *search = sta_->search();
search->deletePathGroups();
// No crash
EXPECT_FALSE(search->havePathGroups());
}
TEST_F(StaInitTest, SearchHavePathGroups) {
@ -3072,8 +3105,9 @@ TEST_F(StaInitTest, SearchHavePathGroups) {
TEST_F(StaInitTest, SearchEndpoints) {
Search *search = sta_->search();
// Without graph, endpoints may be null
// Just exercise the call
ASSERT_NE(search, nullptr);
EXPECT_EQ(sta_->graph(), nullptr);
EXPECT_THROW(sta_->ensureGraph(), std::exception);
}
TEST_F(StaInitTest, SearchRequiredsSeeded) {
@ -3094,30 +3128,31 @@ TEST_F(StaInitTest, SearchArrivalsAtEndpointsExist) {
TEST_F(StaInitTest, SearchTagCount) {
Search *search = sta_->search();
TagIndex count = search->tagCount();
EXPECT_GE(count, 0u);
EXPECT_EQ(count, 0u);
}
TEST_F(StaInitTest, SearchTagGroupCount) {
Search *search = sta_->search();
TagGroupIndex count = search->tagGroupCount();
EXPECT_GE(count, 0u);
EXPECT_EQ(count, 0u);
}
TEST_F(StaInitTest, SearchClkInfoCount) {
Search *search = sta_->search();
int count = search->clkInfoCount();
EXPECT_GE(count, 0);
EXPECT_EQ(count, 0);
}
TEST_F(StaInitTest, SearchEvalPred) {
Search *search = sta_->search();
// evalPred should exist after makeComponents
// (may be null without graph though)
ASSERT_NE(search, nullptr);
EXPECT_NE(search->evalPred(), nullptr);
}
TEST_F(StaInitTest, SearchSearchAdj) {
Search *search = sta_->search();
// searchAdj may be null without graph
ASSERT_NE(search, nullptr);
EXPECT_NE(search->searchAdj(), nullptr);
}
TEST_F(StaInitTest, SearchClear) {

View File

@ -1775,8 +1775,10 @@ TEST_F(SpiceDesignTest, HoldTimingPaths) {
10, 1, false, false, -INF, INF, false, nullptr,
false, true, false, false, false, false
);
// Hold paths should exist for the constrained design
EXPECT_GE(path_ends.size(), 0u);
// Hold paths should exist for the constrained design.
ASSERT_FALSE(path_ends.empty());
ASSERT_NE(path_ends[0], nullptr);
EXPECT_NE(path_ends[0]->path(), nullptr);
}
// Verify clock can be found for SPICE waveform generation