Maybe I am missing something, but how else would I test various exception handling paths?
There is a whole world of errors that can occur during IO. What happens if I get a 500 from that web service call? How does my code handle a timeout? What if the file isn't found?
It is often only possible to simulate these scenarios using a mock or similar. These are also code paths you really want to understand.
Put a small data interface around your IO, have it return DATA | NOT_FOUND etc.
Then your tests don't need behavioral mocks or DI, they just need the different shapes of data and you test your own code instead of whatever your IO dependency is or some simulation thereof.
Sure. This is a good practice for multiple reasons. However, the code that glues my interface to the underlying I/O is still there and needs testing, right?
I agree with you in general. But it always feels like there are spots where a mock of some kind is the only way to cover certain things.
You could call the data you generate for the tests "mocks".
But they really aren't "mocks" in the sense of behavioral mocks via IoC/DI and you don't need to manipulate them via some kind of interface in order to put them into the right state for your particular tests.
There are some extra steps, but you get extremely simple and reliable tests in return.
In many(!) cases you already have a data interface, especially with HTTP/REST APIs. All you need to do is simply not bury the IO call down the stack and maybe describe the failure conditions as plain data in your signature and voila.
(This is not a replacement for higher order testing like, manual, E2E or integration tests. But it certainly beats unit testing with mocks IMO.)
I don't think there's a disagreement; the author states "Whenever I look at mocks, they mostly have the same problem as all unit tests that I see, they only model the happy path". So by corollary their opinion of the correct usage of mocking would also include modelling brokenness.
This is cool. I am going to try it with my kids next time we play.
It also reminds me of a free to play online settlers of catan game from 15-20 years ago. There was no time limit on turns, so people could just grief the game by going AFK.
Aside from charging to put gas in an EV, the amounts they are charging seem really high. How could filling a sedan with gas cost $200 to $400? That’s like 10x what the actual gas costs retail at the pump.
You're paying for convenience. The deal they make with you up front is that you get to not worry about the tank, but in return you pay a super inflated rate for the gas. Plus you pay for a full tank, even if you return it at 3/4 and it only takes a few gallons to fill it.
I get that some people just don't have the time (or executive function?) to deal with refilling before return on some trips, or they're so rich that they just don't care, but otherwise I just do not get why anyone would accept this option.
A lot of car rentals go on a corporate tab. When high-impact employees are traveling, their time is very valuable. An extra 20 minutes for the employee to spend with the customer on the last day could easily be worth $150 to their employer. Some businesses are happy to pay inflated prices for gas just in case their employee needs that extra 20 minutes onsite before returning to the airport.
Actually the deal, typically, is that if you buy a full tank up front, the per-gallon price is at par or even a bit cheaper than local gas stations, so you save money and gain convenience (that's the pitch). By contrast, if you don't buy gas up front, and don't return the car full, that's when they charge you an enormous per-gallon price. That price is highly profitable and also makes the "up-front" option seem more appealing.
(Just take 10 minutes and return the car full, and don't worry about any of this)
If you check what rental companies charge for gas when you pick up a car, they typically list something like $12/gallon here if you don't prepay, and something like $5-7/gallon if you "buy the tank". This vs maybe $3-4/gal at the nearest station.
No, not really - however, based on this post, several people contacted me with questions like these. I asked around and got recommended https://www.amazon.co.uk/Cyber-Persistence-Theory-Redefining... for a more theoretical basis. Haven't read it yet though.
A company called Energy Vault[0] is (was?) working on this. I think it is relatively capital intensive compared to what the company in the article is doing. Of course storing underground requires particular geology.
I also remember reading about a system that moved dirt/rock up a mountain on a train. Can’t find a link, but that also seems capital intensive and requires different geology.
There is also pumped hydro storage that works via gravity. That’s been around a while. My dad worked as an engineer on one in the 80s [1].
We map the TUS[0] protocol to S3 multipart upload operations. This lets us obscure the S3 bucket from the client and perform authorize each interaction. The TUS operations are handled by a dedicated micro-service. It could be done in a Lambda or anything.
Once the upload completes we kick off a workflow to virus scan, unzip, decrypt, and process the file depending on what it is. We do some preliminary checks in the service looking at the file name, extension, magic bytes, that sort of stuff and reject anything that is obviously wrong.
For virus scanning, we started with ClamAV[1], but eventually bought a Trend Micro product[2] for reasons that may not apply to you. It is serverless based on SQS, Lambda, and SNS. Works fine.
Once scanned, we do a number of things. For images that you are going to serve back out, you for sure want to re-encode those and strip metadata. I haven't worked directly on that part in years, but my prototype used ImageMagick[3] to do this. I remember being annoyed with a Java binding for it.
I just checked my significant locations and all it has is my home. I guess that’s lucky. It usually also has my office where I spend quite a bit of time. Hopefully they recover from whatever outage is going on.
Programming, even when in service of my corporate overlords, is invigorating. Coaxing the machines do my bidding never gets old. I could do it all day and not get tired. During those rare times where much programming is needed, I often lose track of time only to realize I've been at it for 15 hours straight. Its been this way for the nearly 20 years I've been doing it.
Sadly, programming is only a minor part of the job. The further I get, the more that is true. I might only actually program an hour or two a week. The rest is spent in ridiculous meetings, hand holding people who fail to read, trying to coax others to coax the machines to do what is needed, "planning", and similar noise. The only rewarding part is mentoring younger programmers.
I continue to do it because its a safe path to retirement and I am nearly there. My plans for retirement: program stuff I want to program for the pure joy of it.
Very cool. Bookmarked in case I ever need to do this.
I have implemented a transactional outbox in postgres using a simpler version of this plus a trigger to notify listening workers. It worked well and vastly outpaced the inserting processes. It easily handled several million tasks per hour without issue.
It is also nice the article showed the correct CTE based form of the query. It is possible to naively write the query without it and sometimes get way more tasks than you asked for when there are concurrent workers. I discovered that pretty quickly but it had me pulling my hair out…
There is a whole world of errors that can occur during IO. What happens if I get a 500 from that web service call? How does my code handle a timeout? What if the file isn't found?
It is often only possible to simulate these scenarios using a mock or similar. These are also code paths you really want to understand.