Skip to content

Template refactoring + more unittests#33

Merged
agawatw merged 23 commits into
masterfrom
template_refact
Apr 3, 2026
Merged

Template refactoring + more unittests#33
agawatw merged 23 commits into
masterfrom
template_refact

Conversation

@sanbee
Copy link
Copy Markdown
Owner

@sanbee sanbee commented Apr 1, 2026

The major change in this commit is refactoring of the code in clgetBaseCode.h and clgetValp() that reduces the number of templated functions to be maintained to only two.

Also added a few missing API call for dbgcl*() functions (also in clgetValp.cc)

Cleanupin the error handling framework. Added capability to set theYY_INPUT` scanner from API. However, it is not yet possible to set this multiple time dynamically at runtime.

And added some more unittests, most importantly to start testing the interactive modes as well.

sanbee and others added 18 commits March 22, 2026 21:16
                       reporting matching failure.
		       This is in prep to support user-supplied
		       functionls for more sophistacted matching and reporting.
                 Also setting the S->Attributes and ->CLASS bits.
                 and fixed the code to set the Symbol::Attributes
		 and ::Class bits.
                   for T=int,float,bool,std::string

clgetValp.cc: With the clparseVal properly templated, separate
              implementations for T=string or T=std::vector<string>
	      for cl[dbg]getValp aren't necessary.  This reduces
	      the number of template functions by four.

CMakeLists.txt: Removed duplication clparseVal.h

tstcpp.cc, clgetValp.h, clgetBaseCode.h: Date change in Copyright notice.
…work!

              (see commented code)
SetVar.cc: Re-set S->Val in case of error during parsing/setting values.
Some cleanup + adding more unit tests.
               a function for scanning input stream for parsing.
clgetBaseCode.h: Throw exception if the searched symbol is not found.
test_parafeed_noninteractive.cpp: Not-yet-working attempts at
                                  setting shell_input function.
                Nominal support for setting the input source for flex scanner
		(see the note below)

test_parafeed_{non}interactive.cpp:  Added the interactive test.

Switching the input source of flex scanner does not work within a
single file.  All test in a single file are run in the same process in
GTest.  And I (SB) haven't yet figure out how to set the YY_INPUT
macro to different input sources dynamically at runtime. Therefore,
current the interactive and non-interactive tests are in separate
file.
session get tested.

Add explanatory comments.
@sanbee sanbee requested a review from agawatw April 1, 2026 15:34
@sanbee
Copy link
Copy Markdown
Owner Author

sanbee commented Apr 1, 2026

All iParafeedTests failed in GitHub CI. They all passed on dhruva.

sbhatnag@dhruva>ctest
Test project /home/dhruva/disk1/sanjay/Packages/parafeed/build
    Start 1: ParafeedTests
1/2 Test #1: ParafeedTests ....................   Passed    0.01 sec
    Start 2: iParafeedTests
2/2 Test #2: iParafeedTests ...................   Passed    0.01 sec

100% tests passed, 0 tests failed out of 2

Total Test time (real) =   0.02 sec

I am not sure why.

Comment thread code/clgetValp.cc Outdated
Comment thread code/clgetValp.cc Outdated
@agawatw
Copy link
Copy Markdown
Collaborator

agawatw commented Apr 2, 2026

All iParafeedTests failed in GitHub CI. They all passed on dhruva.

sbhatnag@dhruva>ctest
Test project /home/dhruva/disk1/sanjay/Packages/parafeed/build
    Start 1: ParafeedTests
1/2 Test #1: ParafeedTests ....................   Passed    0.01 sec
    Start 2: iParafeedTests
2/2 Test #2: iParafeedTests ...................   Passed    0.01 sec

100% tests passed, 0 tests failed out of 2

Total Test time (real) =   0.02 sec

I am not sure why.

As Sanjay mentioned he took short cuts in the sendCmd() function with the assumption that the max_size parameter in ParafeedTest.h::test_shell_input() function is larger than the length of the input string. This can behave “fine” on some machines but fail on GitHub runners due to different compiler/flex buffer behavior. Specifically, the CI unit test reports basic_string: construction from null is not valid. If the scanner/parser state gets corrupted by bad YY_INPUT behavior, we can end up in exactly this kind of failure path.

The fix is to implement test_shell_inp as a proper chunked reader and this should eliminate the divergence of unit tests by CI and local machines.

The suggested fix is as followed.

--- a/code/test/unittest/ParafeedTest.h
+++ b/code/test/unittest/ParafeedTest.h
@@ -1,65 +1,70 @@
#include <gtest/gtest.h>
#include <cl.h>
#include <clgetValp.h>
#include <clsh.h>
#include <clinteract.h>
#include
#include
#include
+#include <algorithm>
#include <readline/readline.h>

string cmd_g;
bool firstPass=true;
+size_t cmd_pos_g=0;
class ParafeedTest : public ::testing::Test {
public:
~ParafeedTest()
{
clCleanUp();
// Reset the input mechanism for the scanner/parser
set_shell_input(backup_cl_shell_input_g);
firstPass=true;
+ cmd_pos_g=0;
}

//------------------------------------------------------------------
// Function that can supply the input to the scanner/parser from a
// string (here the global cmd_g variable).
static int test_shell_inp(char *buf, size_t max_size)
{
- int i=0;
- for (auto c : cmd_g) buf[i++]=c;
+ if (!firstPass || cmd_pos_g >= cmd_g.size()) return 0;

- i=0;
- if (firstPass) {i=cmd_g.size();firstPass=false;}
-
- return i;
+ const size_t n_to_copy = std::min(max_size, cmd_g.size() - cmd_pos_g);
+ std::memcpy(buf, cmd_g.data() + cmd_pos_g, n_to_copy);
+ cmd_pos_g += n_to_copy;
+ if (cmd_pos_g >= cmd_g.size()) firstPass=false;
+ return static_cast<int>(n_to_copy);
}

//------------------------------------------------------------------
// Save the current input function for the scanner before setting
// the scanner another function.
void sendCmd(const string& cmd)
{
cmd_g=cmd;
+ firstPass=true;
+ cmd_pos_g=0;
backup_cl_shell_input_g=get_shell_input();
set_shell_input(test_shell_inp);
}

sanbw added 2 commits April 2, 2026 07:46
              the clgetNValBaseCode() call.  See change request in PR #33.

test_parafeed_interactive.cpp: Typo corrections in the comments.
      (see comments for PR #33)

      Added std:: name space for string and vector<T>

      Reorganized the wrapper for clgetValp() to reduce cognitive
      overload for humans

clgetValp.cc: Reorganized the wrapper for clgetValp() to reduce
              cognitive overload for humans
@sanbee
Copy link
Copy Markdown
Owner Author

sanbee commented Apr 2, 2026

As Sanjay mentioned he took short cuts in the sendCmd() function with the assumption that the max_size parameter in ParafeedTest.h::test_shell_input() function is larger than the length of the input string. This can behave “fine” on some machines but fail on GitHub runners due to different compiler/flex buffer behavior. Specifically, the CI unit test reports basic_string: construction from null is not valid. If the scanner/parser state gets corrupted by bad YY_INPUT behavior, we can end up in exactly this kind of failure path.

The fix is to implement test_shell_inp as a proper chunked reader and this should eliminate the divergence of unit tests by CI and local machines.

The suggested fix is as followed.

Can you send the output of git diff ParafeedTest.h with the above suggested changes separately? I am unable to use the pasted diff in your comment above as a patch.

@agawatw
Copy link
Copy Markdown
Collaborator

agawatw commented Apr 2, 2026

As Sanjay mentioned he took short cuts in the sendCmd() function with the assumption that the max_size parameter in ParafeedTest.h::test_shell_input() function is larger than the length of the input string. This can behave “fine” on some machines but fail on GitHub runners due to different compiler/flex buffer behavior. Specifically, the CI unit test reports basic_string: construction from null is not valid. If the scanner/parser state gets corrupted by bad YY_INPUT behavior, we can end up in exactly this kind of failure path.
The fix is to implement test_shell_inp as a proper chunked reader and this should eliminate the divergence of unit tests by CI and local machines.
The suggested fix is as followed.

Can you send the output of git diff ParafeedTest.h with the above suggested changes separately? I am unable to use the pasted diff in your comment above as a patch.

See attached.
flex.patch

test_parafeed_interactive.cpp: Removed a stray comment not applicable now.
@sanbee
Copy link
Copy Markdown
Owner Author

sanbee commented Apr 2, 2026

The patch for ParafeedTest.h did not fix the failure in iParafeedTest.

The patched however seems like a good improvement, and the ctest on dev machine passes with that patch applied also.

@agawatw
Copy link
Copy Markdown
Collaborator

agawatw commented Apr 2, 2026

The patch for ParafeedTest.h did not fix the failure in iParafeedTest.

The patched however seems like a good improvement, and the ctest on dev machine passes with that patch applied also.

After investigating this further, the issue is in the clTextColouring.cc. When TERM is unset, getenv("TERM") == NULL results in std::string construction from a null pointer. This directly matches the failing exception message (basic_string: construction from null is not valid)

Attached are the patches to fix this issue as well as a new unit test that unsets TERM and verifies clTextColouring(...) does not throw, then restores the environment variable afterward. I've tested this with env -u TERM ctest to unset TERM, mimicking what the CI runner may have.

termtest.patch

colour.patch

@sanbee
Copy link
Copy Markdown
Owner Author

sanbee commented Apr 3, 2026

Attached are the patches to fix this issue as well as a new unit test that unsets TERM and verifies clTextColouring(...) does not throw, then restores the environment variable afterward. I've tested this with env -u TERM ctest to unset TERM, mimicking what the CI runner may have.

This is impressive debugging! Now that you found it out, it also makes good sense.

Since you found it, do you want to apply the patch and push on this branch? That would be appropriate too.

…en TERM is unset

(i.e. getenv("TERM") == NULL), avoiding std::string construction from a null pointer.

Added a new unit test that unsets TERM and verifies clTextColouring(...) does not throw,
then restores the environment variable afterward.
Copy link
Copy Markdown
Collaborator

@agawatw agawatw left a comment

Choose a reason for hiding this comment

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

All issues have been fixed.

@agawatw agawatw merged commit efcc22d into master Apr 3, 2026
2 checks passed
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