Hacker Newsnew | past | comments | ask | show | jobs | submit | brandur's commentslogin

Article does a great job of conveying the stress involved for a non-actor to play even a tiny part in a big movie like this, but yeesh, it'd be a dream come true to get even the tiniest part in one of the greatest movies of all time (IMO obviously), let alone to luck into it this way by pure happenstance.

I remembered the scene vaguely, but was curious to go back and see it. It happens at roughly 7 minutes 19 seconds into the movie, intercut into the initial awards scene, and right before Willem Dafoe's nephew gives Steve a seahorse in a bag.


This is a distinction without a difference. Arko proposed to receive a copy of all RubyGems access logs containing full user PII.

He'd accept this PII en lieu of dollars for secondary on call coverage, so a safe assumption is that he intended to monetize the extracted user PII in some way. I am sure he would deny this, but there's a point where you have to let the evidence we do have combined with common sense guide us to the most likely conclusion.


Thanks for that — I didn't know about `clone` (and important to note it's non-default) and now intend to try it out.


I'm actually curious if this is faster than a tmpfs clone, I suspect it might be as depending on how many underlying files it's copying, it might effectively be doing "nothing" for each file.

Obviously operations after that will be a lot slower reading / writing to a normal disk


As long as you're using Postgres, I would definitely try out an approach based on template databases in your situation. It should check all the boxes that a run with `db/seed.rb` would, except an order of magnitude or two compared to what Rails would be doing (i.e. parsing a big Ruby file and loading schema in table by table).

One of the best things about LLMs is they make these sorts of refactors entirely plausible even if you're not a subject area expert. You could probably prototype this and have a patch ready in an hour or two.


It doesn't look like MySQL has any concept like a template database. You could still migrate up a pristine database, use mysqldump to produce a schema, then load that into a series of test databases. It of course won't be as quick as the low level copies that Postgres is doing with a template database, but it'd be faster than re-running all your migrations.

OOC — I've been trying to gather real world anecdotes on who is using MySQL these days given that even some of its biggest traditional champions like PlanetScale are talking a lot more about Postgres recently. Are you using MySQL as part of an existing project that was started years ago, or do you still intend to use it for new things going forward?


MySQL has a lot of broken "features" that sadly some existing legacy code might be relying upon and there just isn't engineering capacity required to move to a saner DB, so they have to make do.

I had a legacy project on MySQL that turned out to only "work" because string lookups were case-insensitive in that particular version or our configuration. Moving to Postgres and its correct behavior suddenly exposed a lot of bugs we needed to fix before we could complete the migration.


Case sensitivity/insensitivity is a property of the collation, which is configurable on a per-column basis.

In Postgres the default collation is case-sensitive, and in MySQL the default collation is case-insensitive, but this does not mean one is "correct behavior" and the other is not. MySQL's out-of-the-box collation support is arguably a lot more thorough than Postgres's!


No worries Peter. And thanks for putting together pgtestdb — such a great project! This conversion sprint was a fun little experiment.


Some very significant disadvantages to that approach:

* It's common these days for a single operation to manipulate dozens or even hundreds of database records. Often these records are interrelated because they reference each other. So with fakes, you're faking initial inserts and then faking inserts based on other fake inserts, creating a fragile tree structure of fakes, which models reality very poorly.

* No data type validation on data inserts or updates. Put a string in the integer field? Find out in production.

* No foreign key validation (or just general capacity for checking referential integrity) so you don't find out that you're rows aren't referencing each other correctly until production.

* Similarly, no checks on primary keys, check constraints, triggers do not run, etc.

* Since you're not doing real inserts, you're not doing real updates or deletes on inserted rows. So if those latter operations are referencing the wrong ID, you don't find out until ... you guessed it, production.

* You can try to build up the fidelity of your repository/fake framework, but the more effort you put into it, the closer you are to just rebuilding a database and the slower it'll get. You'll also never achieve actual parity with what your database is doing.

* Building out these big fake frameworks is a lot of work relatively speaking (you didn't need to build out anything for your DB because your non-test code is already using it), and gets you negative gain.

There was a time a long time ago when disk I/O was a lot slower than it is now and maybe there was some argument for a repository/stub system, but that was at least a decade ago, and even then the rationale was thin. These days we have NVMes, and if you're a real speed demon and think those are too slow, you can just put an in-memory SQLite or Postgres in place for your testing and get all the performance advantages with none of the downside.


* You're just describing arranging the test setup, which is independent of storage medium.

* Is your repository interface untyped?

* Depends on the fidelity of your fake, but generally I find FKs to be an antipattern these days.

* What are you checking primary keys FOR? Uniqueness is easy and I avoid more complex constraints and triggers.

* ... I'm beginning to suspect we have a difference in terminology. I'm not saying a mock. A typical DB fake would be array or hash table backed in memory. So an insert is "real" and an update or delete would be too.

* Well, sure, but I can get 95% fidelity for 1% of the resources.


Even if the fake is super-fast compared to postgres (1%) in CPU resources: Why spend extra engineering effort to build something that has less fidelity?

CPU for test runs is cheap... and if you use any AI agent at all, tests runs faster than the agent does work. Why does it matter how much faster they run?

The goal of a regression test suite is to catch issues before you deploy to prod. That 95% is a nagging source of doubt. CAN you just release the code straight to prod? Or not?

Many times integration tests including the real postgres and real migration catches bugs for me before they go to prod.

Personally I would just never go with 95% fidelity in tests. Testing with the real postgres is just so good.

And just to get test coverage for the migrations themselves?

(In my case I also use stored procedures, RLS etc that needs those; with your setup that is just not on the table I think or you loose coverage of critical code.)


Interesting. How many database copies do you bring up when the test suite starts running, and how is parallelism handled?


We use pytest with xdist and we run as many as the system it is running on can handle. Each xdist process creates and sets up it's own test_db with a unique name (and drops it at the end of its run if possible). Setup and teardown are done via hooks in pytest. The advantage of this is the test run just needs a db running it can create a testdb on and connect to, so I can have tests running on 5 different branches or workdirs and they don't interact at all. On my threadripper machine with 256GB I could run about 60 concurrent tests, on my 9955hx machine I use day to day I can run 13. On a MBP I think it's about 8-16. There is diminishing returns with more processes.

If I was designing it from scratch I would use a single testdb and point all the python processes at it, and never clean up between tests or even between test runs. This is both faster and a better test, as I feel that clearing the db makes it very hard to detect overly broad queries unless you go out of your way to pack in a lot of extra harness data which people almost never do and is a chore.


Yeah, I've generally recommended using test transactions during test cases [1] as they're extremely fast. I'm open to alternatives like Peter's approach here though because the template approach has some major advantages. The biggest one is that because a database isn't rolled back, state is left around for a failing test, and that can occasionally be really useful when trying to debug a particularly difficult test bug.

Test transactions do occasionally cause other trouble too. DDL is theoretically transaction-safe in Postgres, but when running concurrent schema changes even in test isolation, you can still have tests that leak into each other. Testing anything based on listen/notify is also difficult in a test transaction.

Probably not a bad strategy is to have both tools available in your test helpers: (1) test transactions for the common case, and (2) template databases when you need more isolation.

However, as I alluded to in the second part of the article, in River we're currently using an approach similar to template databases in that every test case operates in its own isolated schema, but with the twist that we also reuse schemas after successful tests, saving us a lot of time in setup costs and bringing us back closer to test transaction performance. Great isolation and our tests are extremely fast, so it's working well.

---

[1] https://brandur.org/fragments/go-test-tx-using-t-cleanup


Peter actually makes this exact point in the project's README. See this section here:

https://github.com/peterldowns/pgtestdb#how-do-i-make-it-go-...

I'd just say that a nice thing about it on disk (even if you disable fsync) is that in case of a failing test, you can examine the post-run state which is occasionally extremely valuable.


Yup! If you keep your laptop on, failing dbs are investigable on tmpfs too — works fine for debugging a few tests in a loop, just can’t run the tests, sleep the computer, have lunch, and come back.


Ah yep, good point. I was confusing "ramdisk" versus just "ephemeral in-memory".


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: