-
Notifications
You must be signed in to change notification settings - Fork 72
Conversation
7cf9914
to
f7b8e41
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm getting this odd feeling of deja vu that some of these comments I'm making here we've already discussed prior during calls or in previous iterations of this PRs. Just because it's a different PR doesn't mean the issues don't still need to be addressed.
I have significant issues with how you've defined SimulatorInterface
, details in the line-by-line comments. This really seems like the kind of thing that should be discussed beforehand, probably even at the concept stage before you've started writing lots of code around it - because otherwise (and as we're seeing now) you might have a lot of code to re-write.
case se: StageError => | ||
se.getCause match { | ||
case exception: FailedExpectException => | ||
val scalatestException = new TestFailedException( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO check exception printout on console
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has been tested in the chiseltest.tests.BasicTest
val scalatestException = new TestFailedException( | ||
exception, | ||
exception.stackTraceElements.indexWhere(ste => | ||
ste.getClassName == "chiseltest.package$testableData" && ste.getMethodName == "expect" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you already do the stack trace pruning in phase 2? Why is it done again here? Can you also define in the class TestFailedException where the stack trace should begin so it's part of the interface definition?
Alternatively, TestFailedException doesn't really need the particular StackTraceElement, if the stack trace associated with the exception is properly pruned?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you already do the stack trace pruning in phase 2? Why is it done again here?
This was a bug fix for scalatest, I didn't run scalatest on phase 2.
Can you also define in the class
TestFailedException
where the stack trace should begin so it's part of the interface definition?
I think we can define it in a implicit def under ChiselScalatestTester
, if we do that, TestFailedException
will explicitly depend on ScalaTest
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you already do the stack trace pruning in phase 2? Why is it done again here?
I git blame this. it was bug fixes. In phase 2, I didn't test the code, I fix those bugs introduced by this refactor on phase 4, so it might contain related changes.
Can you also define in the class
TestFailedException
where the stack trace should begin so it's part of the interface definition?
fixed.
Alternatively,
TestFailedException
doesn't really need the particularStackTraceElement
, if the stack trace associated with the exception is properly pruned?
Fixed.
package chiseltest.backends | ||
|
||
import firrtl.AnnotationSeq | ||
import logger._ | ||
|
||
import scala.sys.process.ProcessLogger | ||
|
||
/** [[SimulatorBackend]] is used to generate a binary executable. | ||
* It should will compile FIRRTL to a [[SimulatorInterfaceAnnotation]]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"should will"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
expectStackDepth != 0, | ||
s"Failed to find expect in stack trace:\r\n${trace.getStackTrace.mkString("\r\n")}" | ||
val fullStackTraces = (trace.getStackTrace ++ getParentTraceElements).filterNot(ste => | ||
ste.getClassName.startsWith("chiseltest.internal.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This significantly changes the behavior - this is filtering out, instead of filtering all before or after. The criteria is also looser. Both are subtle, but makes the code more brittle.
Yes, I know that under the old one, changes elsewhere means this also needs to be changed too. But we have tests to catch that, and I'd prefer code errs on the stricter and safer side.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BasicTest
has correspond test on this.
maybe you can take a review on running chiseltest.tests.BasicTest
:
it should "fail on expect mismatch" in {
assertThrows[exceptions.TestFailedException] {
test(new StaticModule(42.U)) { c =>
c.out.expect(0.U)
}
}
}
And FaultLocatorTest
work well under this refactor.
simulatorInterface.peek(dataNames(clk)) match { | ||
case Some(x) if x == BigInt(1) => true | ||
case _ => false | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in a previous phase, these should fail noisily. Similarly below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add an additional API to enable/disable this.
In the future, it's possible to peek a non-exist(constant-propagated) target inside Module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you give me a use case where you would want to peek a non-existent target and where some arbitrary result would be useful?
Like, I can see the utility of maybe peekOption -> Option[BigInt]
, and punt to the upper layer to deal with what happens on a None / nonexistent wire, but I don't think (and I feel strongly about this, unless you have solid arguments the other way) anything should ever create results out of thin air, because this kind of non-intuitive data (even if expedient now) can lead unsuspecting users down a fruitless debugging rabbit hole.
And even with peekOption, I'm not sure what would be guidelines for when to use it vs. when not to, and I'd prefer for APIs not to be introduced until we have a reasonable use case for them.
I also feel strongly against a stateful API to toggle this kind of behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example: a API design here:
https://github.com/sequencer/diplomatictester/blob/4284f6919426186cc4d3e752bb0578d3104ce3cd/src/Driver.scala#L99
But corrupt
is eliminated during constant propagation.
And if it directly fails:
https://github.com/sequencer/diplomatictester/blob/4284f6919426186cc4d3e752bb0578d3104ce3cd/tests/src/dutIOSpec.scala#L46
won't be able to run.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The key issue of this is: If we are peeking/poking a constant-propagated target, what behavior should be?
Or we can dontTouch
those signal explicitly, and throw it like you said.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say the behavior should be to crash. Sure, a zero might work in the use case you have now, but might not work in another use case - so it's a bad idea to hardcode values created out of nothing. With a crash, at least it's noisy and the user gets a stack trace indicating what failed, and can add the needed dontTouch annotations. Compared to creating values - the user might just see a failed test, with an assertion that might not trigger until much later (so nothing hinting at the true root cause), with RTL that is actually good, and might not even think about needing the debug the test infrastructure itself.
@@ -233,6 +232,9 @@ package object chiseltest { | |||
Context().doTimescope(() => contents) | |||
} | |||
|
|||
/** get current elapsedTime in nano second. */ | |||
def elapsedNanoSeconds: Long = Context().simulatorInterface.elapsedNanoSeconds() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this should be part of the general public API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API removed
src/test/scala/chiseltest/experimental/tests/VerilatorCoverageTests.scala
Show resolved
Hide resolved
exc.failedCodeFileNameAndLineNumberString.get should startWith ("DecoupledDriver.scala:") | ||
exc.getMessage should include regex ("""\(lines in FaultLocatorTest\.scala:[^\)]*43.*\)""") | ||
exc.failedCodeFileNameAndLineNumberString.get should startWith("DecoupledDriver.scala:") | ||
exc.getStackTrace.mkString("\n") should include regex ("""\(FaultLocatorTest\.scala:[^\)]*43.*\)""") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO see if this behaves properly in ScalaTest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ScalaTest should behave good here, you can directly print out getStackTrace
.
1. Add TestNameAnnotation to get rid of TargetDirAnnotation auto inserting. 2. catch error with pattern match StageError in scalatest. 3. move Context to ThreadedBackend file. 4. update FaultLocatorTest, get rid of old source info. 5. fix for ThreadSafetyLocator. 6. bug fix for 2.11, stacktrace has different depth.
1. don't remove old test file now. 2. use --t-name to override test folder. 3. fix hardcoded path in tests.
f7b8e41
to
1c22b3d
Compare
641536c
to
e49911e
Compare
I'm going to create a commit with all fixes about this review. |
1. change FailedExpectException API, directly use setStackTrace and getStackTrace API from Scala. 2. SimulatorBackend now not extends from LazyLogging. 3. Add trait SubprocessSimulatorBackend to log process stdout and stderr. 4. remove time related API from SimulatorInterface, add it in RecordSimulatorTime trait. 5. SimulatorInterface poke/peek API change to throw SignalNotFoundException if not find a signal in the symbol table. 6. bug fix for not use TestCommandAnnotation. 7. remove stale peek related code. 8. re-add VerilatorCoverageTests. 9. fixes for some typos.
@sequencer what's going on with this refactor? Are things still a work-in-progress, or has this been abandoned? If the former, let me know how I can help speed things along so other changes aren't blocked; if the latter then 🤷 we should at least clarify and get some closure. |
Didn't he already reply to all the code review issues that came up? I see the commit above. |
I think we discussed this during a meeting, and I think the resolution was to avoid incidental refactors so the diff doesn't bloat, and that not everything needed to be an annotation or serializable. I haven't seen any movement since, though. Since this was an one-of meeting (instead of the regularly recurring chisel-dev), I don't know if there was a notes doc. A quick search didn't surface anything. |
In our last meeting, IIRC, these PRs are rejected since it's hard to review. |
Yes, I recall these PRs were rejected because of feature creep too. The original post was more regarding whether you were working on a refactor for dependencyapi that didn't have all the feature / 'cleanup' creep - because my understanding from that meeting was that you were going to do a minimal set of changes to migrate to dependencyapi. Whether you accomplish that be rebasing these commits or starting from 'scratch' (perhaps copying over lines / files to another branch) is up to you, but please smaller, self-contained, single-feature PRs... |
This PR has gotten stale, so I will close is for now. Feel free to re-open. |
Fixes for reviews and CIs