Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CI is inconsistent #669

Draft
wants to merge 2 commits into
base: staging
Choose a base branch
from
Draft

CI is inconsistent #669

wants to merge 2 commits into from

Conversation

rslawson
Copy link
Collaborator

CI seems to fail spuriously on timeouts, almost exclusively on the Vex RISC-V TCP test and in invoking Picocom. However, when certain functions time out, their previously read input is discarded, often along with what's left in the buffer being read from. These should instead probably be printed out on the program's stdout so that CI logs show what occurred prior to the timeout.

Copy link
Contributor

@lmbollen lmbollen left a comment

Choose a reason for hiding this comment

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

Initial review :)

Comment on lines 23 to 38
expectLine :: (HasCallStack) => Handle -> (String -> Filter) -> Assertion
expectLine = expectLine' ""
expectLine ::
(HasCallStack) => Maybe (Int, String) -> Handle -> (String -> Filter) -> Assertion
expectLine Nothing h f = expectLine' "" h f
where
expectLine' s0 h f = do
line <- hGetLine h
expectLine' s0 h' f' = do
line <- hGetLine h'
let
trimmed = trim line
s1 = s0 <> "\n" <> line
cont = expectLine' s1 h f
cont = expectLine' s1 h' f'
if null trimmed
then cont
else case f trimmed of
Copy link
Contributor

Choose a reason for hiding this comment

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

1: We usually prefer to use foo0, f001, foo1 etc over foo, foo', foo'' because it tends to get difficult to read since you have to count the primes.

2: When you have a single worker function we usually call it go to prevent the need of using foo1 or foo'.
3: You can use eta reduction, you don't have to add h and f as arguments of expectLine. You simply return a partially applied go function.

Comment on lines 43 to 48
expectLine (Just (timeout, msg)) h f = do
initTime <- getCurrentTime
expectLine' initTime "" h f
where
timeout' = toRational timeout
expectLine' t0 s0 h' f' = do
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
expectLine (Just (timeout, msg)) h f = do
initTime <- getCurrentTime
expectLine' initTime "" h f
where
timeout' = toRational timeout
expectLine' t0 s0 h' f' = do
expectLine (Just (timeout, msg)) = getCurrentTime =<< go
initTime <- getCurrentTime
expectLine' initTime "" h f
where
timeout' = toRational timeout
go t0 s0 h f = do

Comment on lines 50 to 72
if toRational (diffUTCTime t0 now) >= timeout'
then errorIO $ "expect line timed out on: `" <> msg <> "`. previously read: \n" <> s0
else do
line <- hGetLine h
let
trimmed = trim line
s1 = s0 <> "\n" <> line
cont = expectLine' t0 s1 h' f'
if null trimmed
then cont
else case f trimmed of
Continue -> cont
Stop Ok -> pure ()
Stop (Error msg') -> do
rest <- readRemainingChars h'
putStrLn $ "handle buffer dump:\n" <> rest
errorIO $
"expect line failed on `"
<> msg
<> "`\nmessage: `"
<> msg'
<> "`\npreviously read:\n"
<> s1
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to create a custom return type to differentiate between Success, Timeout and Closed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That I'm not sure of - I'm not entirely certain whether that info is actually useful to the postproc functions since I haven't read over them properly, just updated the call locations for the functions I changed.

line <- hGetLine h
let
trimmed = trim line
s1 = s0 <> "\n" <> line
Copy link
Contributor

Choose a reason for hiding this comment

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

I think I'd rather see a list of lines of type [String] rather than reading on a per line basis and then manually re-inserting new lines. You can easily convert [String] to String using unlines.

Stop (Error msg') -> do
rest <- readRemainingChars h'
putStrLn $ "handle buffer dump:\n" <> rest
errorIO $
Copy link
Contributor

Choose a reason for hiding this comment

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

You seem to trade assertFailure for errorIO, is there a reason for that?

Comment on lines 78 to 88
-- Create function to log the output of the processes
loggingSequence = do
threadDelay 1_000_000 -- Wait 1 second for data loggers to catch up
putStrLn "Picocom stdout"
picocomOut <- readRemainingChars picocomStdOut
putStrLn picocomOut
case maybePicocomStdErr of
Nothing -> pure ()
Just h -> do
putStrLn "Picocom StdErr"
readRemainingChars h >>= putStrLn
Copy link
Contributor

Choose a reason for hiding this comment

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

I see you are removing picocom stderr printing from the logging infra, do you think we don't need it?

Copy link
Collaborator Author

@rslawson rslawson Nov 12, 2024

Choose a reason for hiding this comment

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

Mostly just wasn't sure how to integrate it into the new stuff. I would probably have to include another argument to the function, something like onErr which would run in the error branches, but I'm not sure if that would be overcomplicating things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1 Review/merge first
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants