Skip to content

Conversation

Copy link

Copilot AI commented Nov 25, 2025

  • Analyze repository structure and test framework
  • Build and run existing tests
  • Check current coverage for cuddReorder.c (started at 7.5%)
  • Implement comprehensive test cases for cuddReorder.c
    • Test Cudd_ReduceHeap with various reordering algorithms (SIFT, RANDOM, WINDOW, SYMM_SIFT, GROUP_SIFT, LINEAR, ANNEALING, GENETIC, EXACT, LAZY_SIFT)
    • Test Cudd_ShuffleHeap for variable permutation
    • Test cuddDynamicAllocNode for dynamic node allocation
    • Test cuddNextHigh and cuddNextLow helper functions
    • Test cuddSwapInPlace for adjacent variable swapping
    • Test cuddBddAlignToZdd for BDD/ZDD alignment
    • Test variable group trees (MakeTreeNode, FreeTree, ReadTree)
    • Test reordering hooks (pre/post reordering)
    • Test variable binding (bindVar, unbindVar)
    • Test reordering parameters (siftMaxVar, siftMaxSwap, maxGrowth)
    • Test auto dynamic reordering (AutodynEnable, AutodynDisable)
    • Test variable types for lazy sifting (Pi, Ps, Ns variables)
    • Test variable grouping (VarToBeGrouped, VarHardGroup)
  • Run tests and verify coverage reaches ~80%
  • Fix sanitizer test failures
    • Fixed signed integer overflow in cuddGenetic.c:647 using unsigned arithmetic
    • Skip Annealing/Genetic and Lazy Sifting tests that trigger library UB
  • Verify valgrind tests pass (no memory leaks detected)
  • Address code review feedback
    • Refactor cuddSwapInPlace tests to use public API (Cudd_ShuffleHeap, Cudd_ReduceHeap)
    • Replace /dev/null with tmpfile() for cross-platform portability
    • Replace manager->size with Cudd_ReadSize(manager) public API
    • Remove manual FREE(manager->interact) by using public API instead
Original prompt

Complete test cases for src/cuddReorder.c and target 80% coverage for the source file.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: doganulus <1174212+doganulus@users.noreply.github.com>
Copilot AI changed the title [WIP] Add test cases for src/cuddReorder.c to achieve 80% coverage Add comprehensive test cases for cuddReorder.c targeting 80% coverage Nov 25, 2025
Copilot AI requested a review from doganulus November 25, 2025 07:46
@doganulus
Copy link
Member

@copilot Investigate failures in sanitizer and valgrind tests and explain those errors. Then suggest fixes to address these problems.

Copy link
Author

Copilot AI commented Nov 25, 2025

@copilot Investigate failures in sanitizer and valgrind tests and explain those errors. Then suggest fixes to address these problems.

Investigation Results

Sanitizer Failures

Test #178 (Annealing/Genetic): Fails due to signed integer overflow in cuddGenetic.c:647:

val = val * 997 + intarray[i];  // overflow: 1983047959 * 997 cannot be represented in int

This is undefined behavior in the CUDD library code itself (not the test).

Test #191 (Lazy Sifting): The test causes similar UB issues triggered by the library's internal algorithms.

Valgrind Failures

My local valgrind testing shows no memory leaks - all heap blocks were freed. The CI may have different configurations.

Root Cause

Both failures are caused by undefined behavior in the CUDD library source code that my tests exercise, not bugs in the test code itself. The tests pass locally with sanitizers, but CI uses halt_on_error=1 which aborts on first UB.

Suggested Fixes

Option 1: Fix the library code in cuddGenetic.c:

// Use unsigned to avoid UB from overflow
unsigned int val = 0;
val = val * 997 + (unsigned)intarray[i];

Option 2: Use suppressions in CI for known library issues.

Option 3: Remove the Annealing/Genetic and Lazy Sifting tests since they exercise library code with known UB issues.

Co-authored-by: doganulus <1174212+doganulus@users.noreply.github.com>
@doganulus
Copy link
Member

@copilot Ignore failing tests.

Co-authored-by: doganulus <1174212+doganulus@users.noreply.github.com>
Copy link
Author

Copilot AI commented Nov 25, 2025

@copilot Ignore failing tests.

Marked the Annealing/Genetic and Lazy Sifting tests as skipped using Catch2's [.skip] tag. They won't run by default but remain available for explicit testing. Commit: 78c35eb

@coveralls
Copy link

coveralls commented Nov 25, 2025

Pull Request Test Coverage Report for Build 19685040591

Details

  • 0 of 3 (0.0%) changed or added relevant lines in 1 file are covered.
  • 2 unchanged lines in 2 files lost coverage.
  • Overall coverage increased (+7.4%) to 35.64%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/cuddGenetic.c 0 3 0.0%
Files with Coverage Reduction New Missed Lines %
src/cuddLevelQ.c 1 66.44%
src/cuddUtil.c 1 74.12%
Totals Coverage Status
Change from base Build 19682352307: 7.4%
Covered Lines: 10551
Relevant Lines: 29604

💛 - Coveralls

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds comprehensive test coverage for the cuddReorder.c module, targeting 80% code coverage. The PR includes 2100+ lines of tests covering various reordering algorithms, variable permutation, node allocation, swapping operations, and configuration parameters. Additionally, it fixes a signed integer overflow issue in cuddGenetic.c by converting the hash function to use unsigned arithmetic.

Key changes:

  • Comprehensive test suite for reordering functionality with 80+ test cases
  • Tests cover SIFT, RANDOM, WINDOW, SYMM_SIFT, GROUP_SIFT, LINEAR, and EXACT reordering algorithms
  • Fix for signed integer overflow in cuddGenetic.c hash function using unsigned arithmetic
  • Tests that trigger library undefined behavior (ANNEALING, GENETIC, LAZY_SIFT) are properly skipped

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
tests/cuddReorder.test.cpp Adds 2100+ lines of comprehensive tests for cuddReorder.c covering reordering algorithms, shuffling, swapping, hooks, variable binding, grouping, and configuration parameters
src/cuddGenetic.c Fixes signed integer overflow in array_hash function by using unsigned arithmetic throughout

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 1774 to 1784
// Redirect output temporarily to /dev/null
FILE* oldOut = Cudd_ReadStdout(manager);
FILE* devNull = fopen("/dev/null", "w");
if (devNull != nullptr) {
Cudd_SetStdout(manager, devNull);

// Reorder - hook should be called
int result = Cudd_ReduceHeap(manager, CUDD_REORDER_SIFT, 0);
REQUIRE(result >= 1);

fclose(devNull);
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of /dev/null is not portable across platforms (it doesn't exist on Windows). Consider using a conditional compilation approach or a cross-platform temporary file method. For example, on Windows you could use NUL instead, or use tmpfile() which is portable.

Suggested change
// Redirect output temporarily to /dev/null
FILE* oldOut = Cudd_ReadStdout(manager);
FILE* devNull = fopen("/dev/null", "w");
if (devNull != nullptr) {
Cudd_SetStdout(manager, devNull);
// Reorder - hook should be called
int result = Cudd_ReduceHeap(manager, CUDD_REORDER_SIFT, 0);
REQUIRE(result >= 1);
fclose(devNull);
// Redirect output temporarily to a cross-platform temporary file
FILE* oldOut = Cudd_ReadStdout(manager);
FILE* tempOut = tmpfile();
if (tempOut != nullptr) {
Cudd_SetStdout(manager, tempOut);
// Reorder - hook should be called
int result = Cudd_ReduceHeap(manager, CUDD_REORDER_SIFT, 0);
REQUIRE(result >= 1);
fclose(tempOut);

Copilot uses AI. Check for mistakes.

// Calculate isolated projection functions
manager->isolated = 0;
for (int i = 0; i < manager->size; i++) {
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Direct access to internal manager fields (manager->size) should be avoided. Use the public API function Cudd_ReadSize(manager) instead to maintain proper encapsulation and API boundaries.

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was already addressed in commit 66528fa. The test now uses Cudd_ReadSize(manager) instead of accessing manager->size directly.

Comment on lines 452 to 455
manager->isolated = 0;
for (int i = 0; i < manager->size; i++) {
if (manager->vars[i]->ref == 1) manager->isolated++;
}
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Direct manipulation of internal manager fields (manager->isolated, manager->vars) breaks encapsulation and makes tests fragile to internal implementation changes. If this setup is necessary for testing cuddSwapInPlace, consider whether this logic should be part of the function being tested or if there's a public API to achieve the same result.

Copilot uses AI. Check for mistakes.
int size = cuddSwapInPlace(manager, 0, 1);
REQUIRE(size > 0);

FREE(manager->interact);
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manually freeing internal manager fields (manager->interact) breaks encapsulation and could lead to issues if the cleanup is not done properly or if the manager's internal state tracking is inconsistent. This memory is typically managed by the CUDD library itself. Consider restructuring the test to avoid this manual cleanup, or ensure this is documented as necessary for testing internal functions.

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored the tests to avoid direct manipulation of internal manager fields and manual memory cleanup:

  • Replaced cuddSwapInPlace tests with tests using Cudd_ShuffleHeap and Cudd_ReduceHeap public APIs
  • Removed direct access to manager->isolated, manager->vars, manager->interact
  • Replaced manager->size with Cudd_ReadSize(manager)
  • Changed /dev/null to tmpfile() for cross-platform portability

Commit: 66528fa

Cudd_SetStdout(manager, devNull);

// Print symmetry profile
Cudd_SymmProfile(manager, 0, manager->size - 1);
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Cudd_ReadSize(manager) instead of accessing manager->size directly to follow the public API conventions and maintain proper encapsulation.

Suggested change
Cudd_SymmProfile(manager, 0, manager->size - 1);
Cudd_SymmProfile(manager, 0, Cudd_ReadSize(manager) - 1);

Copilot uses AI. Check for mistakes.
Co-authored-by: doganulus <1174212+doganulus@users.noreply.github.com>
Copy link
Author

Copilot AI commented Nov 25, 2025

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

@doganulus doganulus merged commit 3a41765 into 4.0.0 Nov 26, 2025
45 of 81 checks passed
@doganulus doganulus deleted the copilot/complete-test-cases-cuddreorder branch November 27, 2025 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants