9 ms·
Step 0: reproducible builds (like you said) Step 1: run all tests, mark all the flaky ones. Step 2: run all tests under sanitizers, mark all the ones that fai
by dataflow 3y ago
Step 0: reproducible builds (like you said)
Step 1: run all tests, mark all the flaky ones.
Step 2: run all tests under sanitizers, mark all the ones that fail.
Step 3: fix all the sanitizer failures.
Step 4: (the other stuff you wrote)
- daemin 3y agoProbably insert another Step 1: implement tests Be they simple acceptance tests, integration tests, or even unit tests for some things.
- eschneider 3y agoJust a note on legacy tests: Step 0.5: understand the tests. They need to be examined to see if they've rotted or not. Tests passing/failing doesn't really mean code under test works or not. The tests might have been abandoned under previous management and don't accurately reflect how the code is _supposed_ to be working.
- dataflow 3y agoI'd put that under 2.5 or 3.5, if not later. You only really need to do it before you start modifying code, and it's a massive effort to understand a new codebase. Better pick the lower-hanging fruit (like corruption bugs) so you can at least stay sane when you run the tests and try to understand them.
- fransje26 3y agoLook at mister fancy here, having tests in his legacy code base.
- mst 3y agoThe same applies to comments. I have absolutely inherited codebases where one of the early steps was to make a commit excising every single comment in the code, because so many of them were old, lies, or old lies, that it wasn't worth the risk of a junior developer accidentally thinking they could be relied upon. (and of course they remained available in history to be potentially buffed up and resurrected, but still, argh)
- dataflow 3y agoThat's brilliant, but also... sounds like hell? Wouldn't that easily add several months to the timeline?
- roland35 3y agoI find it helpful to try and intentionally break the code under test. Sometimes the test still passes, and that is a good sign that something is very wrong!
- Zobat 3y agoMy project has decent code, source control with history from the beginning (ten years in a few months) and unit tests that were abandoned for years. I've spent at least a couple of weeks, over a year or so, just to remove tests that didn't test current functionality and get the others to work/be green. They ain't fast and only semi stable but they regularly find bugs we've introduced.
- hyperman1 3y agoIf we're going to visit the circles of hell, let's do it properly: Step -1: Get it under source control and backed up. Step -2: Find out if the source code corresponds to the executable. Which of the 7 variants of the source code (if any). Step -3: Do dark rituals over a weekend with cdparanioa to scrape the source code from the bunch of scratched cd's found in someone's bottom drawer. Bonus point if said person died last week, and other eldritch horrors lurk in that bottom drawer. Build a VM clone of the one machine still capable of compiling it. Yes, I have scars, why do you ask?
- galangalalgol 3y agoI was assuming it already had unit and system tests with decent coverage. I forgot how bad stuff gets. Maybe VM clones of various users too, and recordings of their work flows?
- Cerium 3y agoI'm always careful to dump the bash history as soon as I get access to a machine involved in a legacy project.
- eschneider 3y agoOooh, smart!
- cqqxo4zV46cp 3y agoYep! Learned this one the easy way! I don’t get to say that often, so I’m taking full advantage.
- eschneider 3y agoThere was that time when I had to dump the roms off a 'test' MRI machine because that's the only version of the code they had, then decompiled it, and rewrite it from that. I think about that a lot now that I'm older and spend a fair bit of time in MRI machines...
- groby_b 3y agoStep 0 sounds so easy. Until you realize __time__ exists. Then you take that away, and you find out that some compiler heuristics might not be deterministic. Then you discover -frandom-seed - and go ballistic when you read "but it should be a different seed for each sourcefile" Then you figure out your linker likes emitting a timestamp in object files. Then you discover /Brepro (if you're lucky enough to use lld-link. Then you used to discover that Win7's app compat db expected a "real" timestamp, and a hash just won't do. (Thank God, that's dead now). This is usually the part where you start questioning your life choices. Then somebody comes to your desk and asks if you can also make partial rebuilds deterministic. On the upside, step 1 is usually quick, there will be no tests.
- dataflow 3y agoI think (well, assumed) what they meant by deterministic builds was merely hermetic builds, which are easier. True determinism is overkill for step 0.
- groby_b 3y agoOften yes. Sometimes, no. You haven't enjoyed C++ until you get reports of the app intermittently crashing, and your build at the same version just won't. But yes, if the goal is "slap it all in a container", that's probably good and at least somewhat reproducible. We aren't Python here! ;)
- boolemancer 3y ago> Often yes. Sometimes, no. You haven't enjoyed C++ until you get reports of the app intermittently crashing, and your build at the same version just won't. That's okay, it's probably just some bank in a random country that requires some software package to be installed, presumably in the interest of security, which injects a dll into every process on the machine and unsurprisingly has a bug which causes your process to crash at random in only that part of the world.
- 3y ago