[HN Gopher] Redbox left PII on decommissioned machines
___________________________________________________________________
Redbox left PII on decommissioned machines
Author : NotPractical
Score : 275 points
Date : 2024-10-16 00:15 UTC (22 hours ago)
(HTM) web link (digipres.club)
(TXT) w3m dump (digipres.club)
| dylan604 wrote:
| Take this as a lesson. If you've been a dev long enough, you've
| worked on a project knowing that how the project is being done
| isn't _the best_ method with every intention of going back to
| make it better later, but not at the expense of getting the MVP
| up and running. You 'll also have seen that never actually
| happening and all of those bad decisions from the beginning still
| living all the way to the bitter end.
|
| I'm guessing not one person involved would have ever imagined
| their code being left on a machine just left out in the open
| exposed to the public completely abandoned by the company.
| Apocryphon wrote:
| One just wonders if the cooperative-multitasking BASIC
| implemented in this machine really was necessary for an MVP.
| Other than if that just happened to be the sort of programming
| that the developer at the time was familiar with.
|
| Also, this really is the 'engineering' discipline with the
| lowest level of craftsmanship and regard for rigor, isn't it?
| Because the failures are usually intangible, not directly life-
| threatening.
| WhyNotHugo wrote:
| When a developer says "this is a temporary solution" they mean
| "this is a temporary solution forever".
| gscott wrote:
| The beta version works fine, lets just keep it.
| Moru wrote:
| Never make the "Proof of concept" so good it is actually
| usable.
| Jerrrrrrry wrote:
| Words to be forever-tentatively employed by :)
| macintux wrote:
| Write the proof of concept in a language that the company
| doesn't want to support. Erlang, Haskell, Prolog.
| Dalewyn wrote:
| There is nothing more permanent than a temporary solution,
| and nothing more temporary than a permanent solution.
| throwaway365x2 wrote:
| That's very true.
|
| When a customer has a problem, you create a solution to it.
| Often the problem is part of a much larger space, so you
| tend to have discussions of all the possible features you
| could implement. This is a necessary step to gain knowledge
| about the problem space, but it can lead you to think that
| the solution have to cover it all
|
| Time restraints leads to a "temporary" feature to solve the
| customer's immediate need. Most of the time it turns out
| that all the other features are neither necessary nor
| important enough to spend time on.
|
| Projects without time restraints or focus tends to create a
| complex system that will "solve" the entire problem space.
| Most of the time it turns out that our assumptions are
| wrong and we need to do a major refactoring.
|
| "Temporary" solutions may not have the best code structure
| or architecture, but it is not necessarily a bad technical
| debt, as many new developers to the project seems to think
| it is. Also, the time restraints of a temporary solution
| encourages the developer to create simple code and not
| "clever" code, because they can always blame time
| restraints for their lack of cleverness. If the code has
| been mostly unchanged for years, somewhat maintainable and
| solves the customer's problems, it's not really a problem.
| pphysch wrote:
| I agree. Temporary / bandaid solutions are totally great
| if they are straightforward to implement AND unimplement.
| iancmceachern wrote:
| They mean temporary for them
| flomo wrote:
| They might have had the most perfectly developed
| decommissioning process. And nobody is going to care when their
| paychecks stop showing up, and everything suddenly gets
| trucked-off into receivership.
|
| Given the era and constraints, I don't see how it was
| irresponsible or 'sloppy' to have a local database on these
| things. This most likely is not on development.
| raffraffraff wrote:
| This.
|
| I often wonder what was left behind when the financial crash
| happened. Watching documentaries and movies about it, it
| looked me like several large banks and insurers closed up
| shop overnight, and people were leaving the next day with
| boxes containing their personal effects.
| qwery wrote:
| I think you're right in general -- that is, regardless of the
| original company's practices, the entity selling off the
| assets should be required to do that responsibly -- but then:
|
| > the unit I've got an image for has records going back to at
| least 2015.
|
| Whether or not it's "on development" -- that's sloppy. Like
| how it would be a problem if your preferred grocery store
| kept your details on the cash register you checked out
| through almost ten years ago. It's a point-of-sale terminal
| holding on to high risk data for no reason.
| flomo wrote:
| I recall being surprised to see people using a Redbox in
| the grocery store. Like, wow, (a) this company still
| exists, and (b) ppl still watch DVDs. And that was years
| ago. I think it's not unlikely the company was already in
| total zombie-mode by 2015.
| dylan604 wrote:
| > and everything suddenly gets trucked-off into receivership.
|
| That's the problem. These things aren't getting collected and
| trucked off. They are just left rotting in their installed
| locations. I'm pretty confident that you could just show up
| to any of these with a tool box to just start opening one up
| to take out whatever you wanted from the insides, and not one
| person would question you. They already said they don't care
| if you never returned any discs you had in your possession,
| so nobody would care if you emptied their inventory of discs
| within. And until now, I'd wager not one person inside the
| company ever thought they might be vulnerable to a PII attack
| like this either.
| Kon-Peki wrote:
| The host locations are pissed off that the machines are
| sitting there taking up space and using electricity. They
| certainly aren't going to be happy with someone opening it
| up and making a mess. Or potentially creating some sort of
| additional liability for them.
|
| But if you show up with a van or a large truck, they'd
| probably pay you money to take the whole thing off their
| hands. And you can tear it apart in your own garage.
| adolph wrote:
| Theres probably lots of great robot disc handler stuff in
| those boxes.
| Kon-Peki wrote:
| There was an article in some source (sorry, I forget
| which) that interviewed a person somewhere in the
| Southeast US that has been paid to remove a dozen or two
| of them. It had some photos of the inside of the machine.
| You should look for it!
| pnw wrote:
| There's a Discord where people are sharing ideas on
| sourcing and modifying the kiosks.
| https://discord.gg/ZNXy722W5t
| mikeryan wrote:
| The end of Chicken Soup for the Soul media (who owned RedBox
| and Crackle at the end) was a complete shit show. I'd be
| unsurprised if they just walked away from the DVD boxes
| leaving the whoever had them on their property with the job
| of dumping them.
|
| CSS just stopped paying vendors before the Redbox acquisition
| to make their balance sheet look better then just never paid
| after that until going bankrupt a year later. (My company was
| a vendor who had to get our attorneys involved to reclaim
| some payment prior to their bankruptcy and will never get the
| rest)
|
| I've seen a bunch of these SPAC style (there's usually some
| sort of penny stock starting point so the company is publicly
| traded from the jump) rollups of bankrupt or failing media
| and entertainment brands over the years and they all blow up.
| guax wrote:
| The good practice of last year is the bad pattern of today.
| _heimdall wrote:
| At least in web development. There's a weird time horizon
| there, the good patterns from a decade ago are often still
| good practices.
|
| Picking up the latest and greatest web stack today will
| likely be a rotting, unused stack next year. Pick up rails or
| django and it will be largely unchanged _and_ you 'll still
| be able to hire for it.
| add-sub-mul-div wrote:
| I love how the all-caps disgust is reserved for the greatest sin,
| the overengineering.
| jordigh wrote:
| Where does Foone keep finding this stuff?
|
| Earlier, Foone finds a NUC:
|
| https://news.ycombinator.com/item?id=41294585
| neonate wrote:
| https://news.ycombinator.com/item?id=41298430 had the comments
| raffraffraff wrote:
| I know an employee in an IT company. He told me that they have
| hundreds of decommissioned laptops and no time to wipe them.
| And they won't pay someone else to do it because it's too
| expensive. So right now they are in storage. If they go bust,
| the storage company will likely dump them.
|
| I've seen a lot of stuff in e-waste. There are several
| facilities within 5 miles of my home, and you can walk right in
| and drop off your old TVs, toasters and laptops in large metal
| bins. And if you have a quiet word with the attendant you can
| usually walk off with stuff that someone else dropped off.
| "Good for the environment mate! I can use this for parts!"
|
| If social engineering works at banks, you can be damn sure it
| works at an e-waste facility. And if that fails, a few bank
| notes help.
|
| I don't do this but I have intercepted e-waste coming from
| family and friends. In one case I found a treasure trove of
| photos from my deceased sister. Nobody had ever seen them
| before. I also found personal documents, internet history and
| saved passwords in the browser, which got me into her iCloud
| account which, until then, nobody could access. This lead to
| more photos and documents. And it was all destined for e-waste.
| michaelt wrote:
| _> I 've seen a lot of stuff in e-waste. [...] if you have a
| quiet word with the attendant you can usually walk off with
| stuff that someone else dropped off._
|
| In my country, there are specialist e-waste disposal
| companies large IT organisations can hire, which guarantee to
| remove and shred the hard drives before recycling the rest.
| theshrike79 wrote:
| "they won't pay someone else to do it because it's too
| expensive"
|
| This is the relevant bit. It's cheaper just to pile the old
| computers in storage vs doing something about it.
| Crosseye_Jack wrote:
| >> And they won't pay someone else to do it because it's
| too expensive.
|
| Its not that such entities that will correctly handle the
| e-waste don't exist, its that the company doesn't want to
| pay to have it donem esp when storage is cheap, let those
| containers of old laptops and towers be someone else's
| (budgetary) problem.
| BlueTemplar wrote:
| I don't think that the people responsible for dealing with
| the mess left from bankruptcy are large IT organizations,
| they probably barely have the money to transport the waste
| to the nearest trash dump, unsorted, and forget about
| "recycling" now that poor countries are less willing to
| take the e-waste.
|
| Companies leaving their waste as someone else's problem to
| deal with is a common occurrence (heck, even before they go
| bankrupt), and in many cases they would never have existed
| in the first place if they had to pay for all of it, for
| instance :
|
| https://www.desmog.com/2019/12/20/fracking-oil-gas-
| bankruptc...
|
| (Note also that there are funds set aside for cleanup, but
| they are typically woefully insufficient.)
|
| How to prevent companies that are a net negative for
| society from existing remains an unsolved problem.
|
| (Aside of course from disallowing companies altogether, I
| wonder when is the point that the limited liability company
| as a concept is a net negative to society ? Could it be in
| the past already ? Of course comes the question of whether
| _any_ alternative can have a positive contribution, in a
| context of overshoot...)
| adolph wrote:
| > guarantee to remove and shred the hard drives
|
| Now that storage is often an indistinct chip on the
| motherboard, I wonder how that works.
| bombcar wrote:
| About as well as it always did, which was some variation
| between "they shredded it whilst I watched" and "they
| probably wiped it before letting someone take it home" to
| "it shows up on eBay in three days untouched."
| cpach wrote:
| Hopefully that company had enabled FDE on those laptops. (It
| still would be prudent to wipe them before recycling, of
| course.)
| protocolture wrote:
| I am loosely aware of a time that a local bank performed a
| large data centre migration.
|
| They built new infrastructure at the new site, then just
| decommed the old building.
|
| Pretty standard stuff, but the old building was like, 1930s
| era or something. After the hardware was deracked, it was
| left in a loading dock, in a now abandoned building, behind
| an unlocked roller door for like 6 months before it was
| recovered for data destruction.
| hggigg wrote:
| I know someone who worked at a recycler who was paid to
| physically destroy and certify media as destroyed. It took time
| and money to destroy media so it just sat in a warehouse for
| months and the paperwork was lies. Eventually they went
| bankrupt and another company bought the stock and sold it on
| eBay by the palette load as is.
|
| The only companies that do a proper job are the ones that turn
| up to your office and shred the hardware in front of you.
| Paperwork is worth shit otherwise.
| viernullvier wrote:
| In this specific case, they started digging through a HDD image
| that someone else pulled. They're still trying to get hold of
| an actual Redbox machine to investigate the hardware as well.
| protocolture wrote:
| I once worked on an ewaste shipment from a rail carrier.
|
| 99% of the stuff they sent us was boring corporate desktops
| running standard, secure soe.
|
| 1 laptop however, booted into windows with saved credentials,
| connected to a vpn automatically, logged into the rail companys
| in house software automatically, and began displaying what I
| can only _assume_ was a live map of the rail network. Little
| green lines running along red lines, the green lines would come
| to junctions and stop. It had buttons. I think I shucked the
| hard drive and drilled it within 60 seconds and had the
| hardware completely disintegrated.
|
| One other time a games company that got liquidated sent us a
| pallet of computers that had source code for a relatively
| popular strategy game on the drives.
|
| Another games company shipped us their test kits one of which
| had a dev build of a relatively well known action adventure
| game. The warehouse guys would play the dev build of the game
| on their lunch breaks.
|
| Basically no one gives a shit.
|
| All of that before I worked for a business that stored their
| customer info including credit cards in plain text one dirwalk
| away on their public website. When we complained we were told
| that it was fine because they "encrypted" the card numbers. The
| encryption was adding 1 to the card number. I died.
| excalibur wrote:
| I just watched a video earlier today about how if you find a
| working redbox, you can get movies out of it without getting
| charged, although you still have to enter your payment info. This
| prospect suddenly sounds even less appealing.
|
| https://www.youtube.com/watch?v=ucsYziSl7xk
| JKCalhoun wrote:
| Seen what the rentals _are_ on a Redbox?
|
| Every time I would go browse their movie collection I always
| walked away uninterested in anything. Most of it was what I
| call direct-to-inflight-video.
| shiroiushi wrote:
| Judging by the movies I've seen on international flights in
| the past few years, I think this is really unfair to inflight
| video. (i.e., the available movies were all highly-rated
| theater movies, not direct-to-video garbage.)
|
| Perhaps a better description would be "even worse than
| Netflix originals"...
| Larrikin wrote:
| I question if this has ever been true outside of old timey
| planes of decades back where everyone had to watch the same
| movie. If you were on a decent international flight you
| could sometimes even see a movie still in theaters.
|
| The only real regression I've seen in my life time in in-
| flight entertainment is ANA removing their partnership with
| Nintendo to run SNES emulators to all the seats. A 14 hour
| flight to Narita used to involve Super Mario All Stars
| ipaddr wrote:
| I didn't bring 5 dollars cash the first time I took a
| plane to SF from the east coast. You end up watching a
| movie on a projector screen without sound. I end up
| reading through Microsoft foundation classes books. On
| the way back I had my 5 dollars ready.
|
| The movie was about a brother who returns to a small town
| to visit his sister in a southern town. He ends up
| staying and helping her with the kids. But his
| irresponsible ways causes frustration with the sister and
| the kids he is watching. He leaves. End of movie.
|
| Truly awful. I wonder what the first movie was like.
| vitorfblima wrote:
| I'm 'kinda curious to know which movie is this.
| ipaddr wrote:
| I've been trying to figure it out for awhile.
|
| It would be in the early 2000s. Let me try AI. Found it.
| What an age we live in.
|
| You Can Count on Me - 2000 Sammy is a single mother who
| is extremely protective of her 8-year old son. She is
| satisfied with living in the small town she grew up in
| and working in a local bank. When her brother Terry
| visits he fits the void in the life of both her and her
| son. Temporarily free of the constraints of single
| motherhood she begins to break free of her normal
| routine. In a string of traumatic events Sammy is torn
| between helping her brother and her maternal instinct to
| protect her son from getting hurt.
|
| 95% rotten tomato score. Someone liked it.
| misiek08 wrote:
| I would to see people start engineering instead of
| overengineering, being scared of such exposure happening to them.
| The only thing I can't disagree more - it's not the graduates who
| write ServiceFactoryBuilder where I work at. Those are guys after
| 12-15 years, started with bad PHP, now being "Senior Java", but
| they didn't learn much since beginning. This is how corporate
| software looks like.
| eichin wrote:
| "1 year of experience, 15 times"
| biofox wrote:
| I feel like if we stopped trying to reinvent the wheel, and
| senior devs had 12-15 to master one version of the wheel,
| things would be much better.
| Spivak wrote:
| Any C# devs wanna explain the XML thing? To me having a separate
| class to deserialize each kind of XML document to its respective
| object seems nice and the "right" way to use XML. The class just
| becomes the config file. Generic loaders but poking at the tree
| is super brittle. Does C# come with magic to do this better?
|
| Because if you have to invent the config file then isn't that
| creating a DSL and we're back to over engineering?
| paranoidrobot wrote:
| I stopped reading when it got all shouty, and a quick scan
| doesn't show whether it's got actual sample code.
|
| It's also been a long while since I wrote any C# for real, and
| even longer since I had to deal with .NET's XmlSerializer.
|
| It used to be a pain in the backside to deal with XML in .NET
| if you wanted to just deserialise a file to an object. You'd
| need to mark up the class with attributes and stuff.
|
| I remember being very happy when JSON.NET came out and we could
| just point at just about any standard object and JSON.NET would
| figure it out without any extra attributes.
|
| I'm not sure if XmlSerializer ever caught up in that regard.
|
| e: Also, without seeing the code and where else it might be
| deployed it's not easy to know whether this is a case of over-
| engineering.
|
| This same code might be deployed to a phone, webserver, lambda,
| whatever - so having an IConfigFileLoader might make 100% sense
| if you need to have another implementation that'll load from
| some other source.
| MarkSweep wrote:
| > I'm not sure if XmlSerializer ever caught up in that
| regard.
|
| Not really. The one thing that exists to make this easier is
| xsd.exe, which can generate the code for these classes from
| and XML Schema file.
|
| https://learn.microsoft.com/en-
| us/dotnet/standard/serializat...
| jonathanlydall wrote:
| Active C# dev here, but I haven't read the article.
|
| For configuration these days XML is generally not used, they
| have a configuration system which can use a variety of
| underlying sources (like environment variables and JSON files)
| and you can either access these settings by key from a
| dictionary or trivially hydrate a plain old C# classes,
| including with collections.
|
| People may still manually read their own configuration
| independent of this system or perhaps they're just generally
| deserialising XML.
|
| There are (I think) at least a few ways to work with XML in
| .NET.
|
| For well known schemas I definitely generally recommend the C#
| class approach where you somewhat simply deserialize a file
| into well typed C# classes.
|
| From your question it sounds like the XML API which allows you
| to arbitrarily query or manipulate XML directly was used here.
| I have on occasion used this when I don't have the full schema
| for the XML available and need to tweak a single element or
| search for something with XQuery. It's a useful tool for some
| scenarios, but a poor choice for others.
| Adachi91 wrote:
| System.Xml has been around for a very long time. I use it in
| one of my tools as a MSN deserialization class to make all my
| old MSN history "readable" by traversing the nodes and
| picking out sending/receiving user, timestamp, and message.
| marcosdumay wrote:
| > To me having a separate class to deserialize each kind of XML
| document to its respective object
|
| You mean a separate function? Or a separated method in some
| class? (Given that C# can't do top level functions...)
|
| Or else, you may want a type parametrized function that uses
| reflection to populate an object of any class you want. That
| would depend on how many different kinds of file you have, but
| the C# standard library has this function so you just use it.
| asp_hornet wrote:
| Sounds like most idiomatic C# code bases i saw. Words cant
| express how happy i am to be outside that bubble
| auguzanellato wrote:
| Looks like the mastodon instance got the HN hug of death, anybody
| archived it?
| dbg31415 wrote:
| I mean that's scary, but at this point is there anybody to hold
| accountable?
| theanonymousone wrote:
| > JUST READ THE FUCKING JSON FILE YOU ENTERPRISE FUCKERS
|
| On a codebase I worked on, accepting an expanded range of data in
| a field required modifying seven files in three repositories and
| two (or three) programming languages. Someone thought that's the
| right way of doing it.
| larodi wrote:
| Are there any laws in any country governing how such equipment is
| supposed to be decommissioned in case if bankruptcy?
|
| This does not seem to be an isolated case, it just happening more
| and more with advance of technology.
| nextlevelwizard wrote:
| What are they going to do? Sue the bankrupted company?
| michaelt wrote:
| If instead of a load of old computers the bankrupt company
| had a pile of old tyres, I'd expect the receivers winding up
| the bankrupt company would dispose of the old tyres properly,
| paid for with the company's assets before anything is
| distributed to creditors.
| nextlevelwizard wrote:
| If someone creates this fucked up compute stack and handles
| the customer data this poorly, what makes you think they
| would be any better at disposal even if there was some laws
| around it? It is not like law makers have any idea either
| what is going on.
| BlueTemplar wrote:
| They are not the company under discussion.
| Cthulhu_ wrote:
| When a company goes bankrupt, a curator comes in who oversees
| the decomissioning of the company and its assets; I don't
| know if a curator is a government agent or a private company
| (probably either), but they become responsible for the
| company and in this case the customer data.
| larodi wrote:
| Or perhaps make sure it gets sanitised before refurbished and
| resold. I mean bankruptcy always means debt collector tries
| to sale assets to cover for losses, no?
|
| But this does not answer my question. So basically many
| people here are unaware where such legal framework exist at
| all.
| scott_w wrote:
| If a company dealing in toxic chemicals goes bankrupt, is it
| functionally legal to just dump them in the nearby river? I'd
| be amazed if countries don't have legal processes in place to
| deal with situations like this and maybe the courts haven't
| caught up to this use case?
| relaxing wrote:
| We need a Superfund for data spills.
| 01HNNWZ0MV43FF wrote:
| I think there's supposed to be an escrow account where you
| say like "I'm going to handle X amount of petrol / nuclear
| material, here's a big pile of cash set aside for cleanup
| if I dissolve"
|
| One could do the same for pii. Of course it's cheaper not
| to, so I'm not sure if anyone actually does this kind of
| insurance policy
| consteval wrote:
| I think historically in the US that's exactly how it's been
| done, and then we just clean it up later (or never). In the
| meantime a bunch of people get sick
| xnorswap wrote:
| > Redbox.HAL.Configuration
|
| > .ConfigurationFileService implements IConfigurationFileService
|
| > STOP MAKING SERVICES AND FACTORIES AND INTERFACES AND JUST READ
| THE FUCKING
|
| > JSON FILE YOU ENTERPRISE FUCKERS
|
| I know it's cool to "hate" on OO, but "just read the fucking
| file" doesn't work if you want to run your unit tests without
| reading a fucking file.
|
| It makes sense to abstract configuration behind an interface so
| you can easily mock it our or implement it differently for unit
| testing.
|
| Perhaps you also want to have some services configured through a
| database instead.
|
| This isn't a ConfigurationFileServiceFactoryFactory.
| rkachowski wrote:
| most of these issues disappear with the introduction of first
| class functions. There's nothing noble about the thick
| indirection inherent in old school enterprise programming.
| gpderetta wrote:
| A fist class function is just an interface. Just ask the
| venerable master Qc Na.
| xnorswap wrote:
| Could or should there just be a `IConfigurationService` instead
| of a separate IConfigurationFileService? Yes, probably.
|
| "Interface all the things" is a bit lazy, but it's easy,
| especially if you have Moq as a way to auto-mock interfaces and
| a DI framework to setup factory methods.
|
| But spinning into rage just because you see an interface or
| abstract factory isn't healthy.
| throwaway365x2 wrote:
| I don't follow .Net closely, but it seems like there should
| be a better alternative. Java has a library called "Mockito"
| that can mock classes directly without requiring an
| interface. I assume something similar exists for .Net, as
| they have similar capabilities. Making an interface for one
| class, just so another class can be tested seems like we
| allow the tool (tests) to determine the architecture of what
| it is testing. Adding complexity in the name of TDD is a
| close second on my list of triggers
|
| There's nothing that triggers* me more than seeing an
| interface that only has one implementation. That's a huge
| code smell and often a result of pre-mature architecture
| design in my opinion. It also often leads to complexity where
| if you have an interface, you create a factory class/method
| to instantiate a "default" implementation. Fortunately it
| seems that it is not used as often as before. Our code has no
| factories and only a few interfaces, that actually have a
| practical use. The same applied to my previous workplace
|
| * The trigger applies to 2024 Java code written as if it was
| 2004. I may have a form of PTSD after many years of
| interfaces and FactoryFactory, but fortunately times have
| changed. I don't see much of that today except in legacy
| systems/organizations.
| xnorswap wrote:
| I'm sure the same exists for .NET ( Moq can probably do it?
| ), but writing against an interface and having concrete
| implementations supplied by the DI framework is pretty much
| the ordained way to do things in .NET.
|
| I used to be in the "Interfaces with only a single
| implementation is a code smell" camp, but I prefer to
| follow the principle of least surprise, so going with the
| flow and following the way the MS standards want you to do
| things makes it easier to onboard developers and get people
| up to speed with your code base. Save "Do it your own way"
| for those parts of the system that really requires it.
|
| And technically the auto-generated mock is a second
| implementation, even if you never see it.
| throwaway365x2 wrote:
| I think you have good approach. I also tend to go with
| the flow and follow the common practice. If I tried to do
| "Java in C#", it would make it more difficult to follow
| my code and decrease maintainability.
|
| I sometimes work on legacy C# code that we inherited from
| another team and I try to follow the style as close as
| possible. I just haven't invested enough time to make any
| informed decisions about how things should be.
| Jerrrrrrry wrote:
| You are both over thinking it.
|
| GIT? unit tests? and i thought debuggers spoiled us?
|
| although cavemen-esque in comparison to 'modernity'; it
| wasn't a nightmare to Pause/resume program flow and
| carefully distill every suspected-erroneous call to
| Console.Log(e)/stdout/IO/alert(e)/WriteLine(e);
| `everything to find the fun/troublesome bits of one's
| program - instead of a tedious labyrinth of stack traces
| obfuscating out any useful information, further insulted
| by nearly un-googable compiler errors.
|
| Tests were commented out functional calls with mock data.
|
| If you never need to instantiate another instance of a
| structure so much so that it would benefit from an
| explicit schema for its use - whether it be an object or
| class inheritance or prototype chain - then sure,
| optimize it into a byte array, or even a proper
| Object/struct.
|
| But if it exists / is instantiated once/twice, it is
| likely to be best optimized as raw variables - short-
| cutting OOP and it's innate inheritance chain would be
| wise, as well as limiting possibly OOP overhead, such as
| garbage collection. >interface in C#
|
| Coincidentally, that is where my patience for abstraction
| for C# had finally diminished.
|
| yield and generators gave off awkward syntatic-over-
| carmelized sugar smell as well - I saw the need, to
| compliment namespaces/access modifiers, but felt like a
| small tailored class would always outweigh the negligible
| time-save.
| Bjartr wrote:
| I love the idea of syntactic engagement gone too far as
| "burnt sugar"
| Kuinox wrote:
| Moq(r) cannot do it. I forked Moq(r) and made a library
| that can mock classes: https://github.com/Kuinox/Myna. It
| can do that by weaving the class you mock at compile time
| for your mocks (you can still use your class normally).
| pylua wrote:
| What's wrong with having an interface with one
| implementation ? It's meant to be extended by code outside
| the current repo most likely. It's not a smell in any
| sense.
| klibertp wrote:
| 90% of single-implementation interfaces (in Kotlin on
| Android projects I've seen) are internal (package/module
| private, more or less.) So no, they are not meant to be
| extended or substituted, and tests are their only raison
| d'etre (irony: I've almost never seen any actual
| tests...) This is insane because there are other tools
| you can use for testing, like an all-open compiler plugin
| or testing frameworks that can mock regular classes
| without issues.
|
| An interface with a single implementation sometimes makes
| sense, but in the code I've seen, such things are
| cludges/workarounds for technical limitations that
| haven't been there for more than a decade already. At
| least, it looks that way from the perspective of a
| polyglot programmer who has worked with multiple
| interface-less OOP languages, from Smalltalk to Python to
| C++.
| throwaway365x2 wrote:
| In that case you have more than one implementation, or at
| least a reasonable expectation that it will be used. I
| don't have a problem with that.
|
| My comment was regarding interfaces used internally
| within the code, with no expectation of any external use.
| I wrote from a modern Java perspective, with mockable
| classes. Apparently interfaces are used by .Net to create
| mocks in unit tests, which could be a reason to use that
| approach if that is considered "best practice"
| gregmac wrote:
| Yeah, IConfigurationService implies separation of concern.
| Code using it doesn't have to care where the configuration
| came from, just that it is there. Someone separately can
| write the concrete
| ConfigurationFileService:IConfigurationService that
| reads/parses files.
|
| IConfigurationFileService implies abstraction of file system-
| based configuration. Are we planning that there's going to be
| a different way to read configuration files in the future,
| and what _exactly_ is that? If no one can articulate it, it
| just seems like architecture astronautism and: YAGNI.
|
| IConfigurationService makes writing unit tests for anything
| that _uses_ it way easier, too. There can be a simple
| TestConfigurationService:IConfigurationService that just
| implements everything as settable, and in your test code you
| can provide exactly the properties you need (and nothing
| more), and easily have 100 variations of configs to ensure
| your code is working. Without the headache of dealing with
| actual files separate from your test code, or worse, shared
| with other test code.
|
| I've actually written multiple long-lived pieces of software
| this way, and more than once ended up implementing stuff like
| environment variable-based configuration, REST API-sourced
| configuration, and even aggregations that combine multiple
| sources, eg: new AggregateConfig(new
| ServerConfig("https://whatever"), new EnvironmentConfig(),
| new FileConfig("/some/path.config"));
|
| All that code that used IConfigurationService is completely
| untouched and unaware of any of this, letting whoever is
| doing this as part of changing deployment (or whatever) be
| productive quickly with very little knowledge of the rest of
| the (possibly massive) app.
| guax wrote:
| Why do you need the interface? You can extend/mock the class
| itself. Refactoring code is easy and cheap. There is no reason
| for complex abstractions that protect implantation outside of
| libraries and frameworks.
| jjice wrote:
| > You can extend/mock the class itself. Refactoring code is
| easy and cheap. There is no reason for complex abstractions
| that protect implantation outside of libraries and
| frameworks.
|
| "Mock" can be a loaded word in this context, so please excuse
| me if I'm looking at it through a difference lens, but if
| you're using some sort of mocking set of tooling (like Jest
| or similar), I'd argue that those mocks are much more
| confusing than an interface with an implementation.
|
| I personally love an interface because it defines the most
| narrow set of operations an object needs to support to be
| passed in, and the implementation of those are completely
| irrelevant for calling. In many cases, I personally find that
| a lot simpler and cleaner to read.
| proikan wrote:
| Isn't ```dependency injection``` (aka passing arguments) the
| big thing that's supposed to solve this? Config
| config; // production config_from_file(&config,
| "config.json"); run_production_stuff(&config);
| // unit tests Config config;
| config_from_memory(&config, &some_test_values);
| run_tests(&config);
| xnorswap wrote:
| Yes, and the typical pattern for .NET DI is to do so with
| interface based parameters.
|
| So let's say you have a service FooService that requires some
| configuration.
|
| ( Ignoring the System.configuration namespace for now)
|
| You'd have: class
| FooService(IConfigurationService ConfigurationService){
| // Access Configuration Through IConfigurationService
| }
|
| Then elsewhere you'd set up your DI framework to inject your
| ConfigFileService to satisfy IConfigurationService in prod.
|
| Yes, it can sometimes feel a bit like "turtles all the way
| down", where sometimes you just wish you had a bunch of
| concrete implementations.
|
| In unit tests, you'd auto-mock IConfigurationService. For
| integration tests you might provide a different concrete
| resolution.
|
| There are some advantages to service based DI though. The
| standard ASP.NET DI framework makes it trivially easy to
| configure it as a singleton, or per-request-lifetime, or per-
| instantiation, without having to manually implement singleton
| patterns.
|
| This gives you good control over service lifetime.
| xnorswap wrote:
| My example above is terrible, because in reality you'd have
| another level before this, which sorts out your global
| configuration, reads it and just injects service specific
| parameters and configuration for each service.
|
| But I just wanted to illustrate idiomatic .NET DI, and on
| reflection picking configuration was probably the worst way
| to illustrate it.
| abrookewood wrote:
| Kind of off topic, but can someone explain why else C# has
| factories and interfaces? Is it just mocking? I really don't
| understand the pattern at all. FWIW I am no dev.
|
| EDIT: Found xnorswap's comment below about configuration, which
| makes sense I get - but as they mentioned, it does feel like
| "turtles all the way down".
| FroshKiller wrote:
| A non-mocking use of mine: I have a factory with a method
| that returns instances of a particular interface for
| publishing typed events to a pub/sub service. The caller of
| the factory doesn't have to be updated with new concrete
| types as new events are added, because it's the factory's
| responsibility to create the events. The event types
| themselves just implement the interface that's required to
| serialize them for the pub/sub service.
| criddell wrote:
| I've used them in the past to keep interface and
| implementation separate. It's an easy way to stick an adapter
| between something concrete and the thing that needs something
| but doesn't care where it's coming from.
|
| So, for example, I could have a IGadgetStore with methods for
| creating, retrieving, updating, and deleting gadget instances
| and then I can have a bunch of different classes implementing
| that interface. An obvious example is to have a
| PostgresGadgetStore and a MysqlGadgetstore and
| CsvFileGadgetStore. If the user wants to implement their own
| store that I haven't written, they can.
| abrookewood wrote:
| OK that makes sense. As an outsider, the C# code bases I
| look at seem to do this as standard practice, even if the
| requirement for different classes never materialises. I
| guess you get used to looking at it, but it seems (perhaps
| naively) as wasteful and a bit distracting.
| nonameiguess wrote:
| I don't think it's off-topic at all. The ideal this kind of
| thing is trying to achieve is separation of concern. One
| developer or team or even entire organization is writing
| things like serializers for specific kinds of file formats or
| other sources of persisted data like databases and
| environment variables or things like the Java Springboot
| externalized config. Another organization is just trying to
| create an application that requires configuration. They don't
| necessarily want to have to worry too much about where it
| comes from. Especially in places that strictly separate
| development and operations, they'll probably have no say
| anyway and it'll change over time and they're not gonna want
| to change their own code when it does.
|
| You can analogize this to non-software use cases. I've got
| phillips head and flathead screwdrivers and ideally don't
| want to have to worry about the specific qualities of a
| particular kind of screw when selecting one. It either has
| one slot on the head or two. That's the interface to the
| screw and it should be the only thing I have to worry about
| when selecting a screwdriver.
|
| Unfortunately, this kind of thing can balloon out of control,
| and in the worst kinds of "enterprise" Java shops I was
| involved in deep into my past, where concrete classes were
| injected at runtime by xml file loaded into the framework, it
| was literally impossible to tell what code was going to do
| simply by reading it, because it is impossible to know what
| is being injected at runtime except by inspecting it during
| runtime. It's a pretty frustrating experience when reading an
| entire code base doesn't tell you what the code actually
| does.
| IggleSniggle wrote:
| > it was literally impossible to tell what code was going
| to do simply by reading it, because it is impossible to
| know what is being injected at runtime except by inspecting
| it during runtime. It's a pretty frustrating experience
| when reading an entire code base doesn't tell you what the
| code actually does.
|
| I've worked in "legacy" nodejs code since node 0.x. Glad to
| hear that there might be hope of codebases that don't have
| this problem. I thought typescript would help, but I've
| learned that fancy generics can ensure that it's still
| quite possible to have no idea what something will actually
| do in a real world environment, you'll just have a lot more
| cognitive overhead in wondering about it.
|
| To be clear, I love ts and fancy generics that try to
| impose a Haskell-like determinacy on js Object structure
| with exclusivity and exception guarantees and all the rest;
| I just also hate it/them, at the same time.
| rcxdude wrote:
| But why is it so hard to read a file during a unit test? Files
| are pretty easy to mock in many different ways, all of which
| are pretty fast. You don't need a special-purpose interface to
| be able to test the code that uses a config file.
| wobblyasp wrote:
| It's not, but maybe I don't want to create a file for the
| tests. The point theyre trying to make is that it's a
| personal preference and not an obvious "this way is better"
| stickfigure wrote:
| Let's say you want to test bootstrapping your system with
| various configurations.
|
| You could make a few dozen different configuration files. Or
| maybe it's more than that because you want to test
| permutations. Now you're maintaining a bestiary.
|
| So instead you think "I'll write code that generates the
| config file for each test". And that's reasonable sometimes.
|
| On the other hand, the single-responsibility principle can be
| reasonably applied here and "reading the config data" is a
| good single responsibility. You don't want to have to write
| code to muck with json or xml every time some component needs
| a configuration value. So there should already be a clean
| boundary here and it often makes sense to test the components
| separately.
|
| There's not one rule. The article author sounds like an
| excitable jr engineer that's never written software at scale.
| dogleash wrote:
| > that's never written software at scale.
|
| Is this like a never version of that insult where people
| would say someone's opinion doesn't matter because they
| worked on a project that never shipped (regardless of how
| much or how little they contributed to the failure)? Just
| replacing it with an AWS bill-measuring contest?
| stickfigure wrote:
| "Software at scale" is different from "data at scale" is
| different from "compute at scale".
|
| But yeah, when I hear "STOP MAKING SERVICES AND FACTORIES
| AND INTERFACES AND JUST READ THE FUCKING JSON FILE YOU
| ENTERPRISE FUCKERS" I think "developer who's never worked
| on anything more complicated than a chat app, and isn't
| old enough to have learned humility yet".
| pphysch wrote:
| > Now you're maintaining a bestiary.
|
| Any battle-hardened test suite is already a bestiary.
| Having a subfolder of diverse & exemplary config files,
| that could be iterated over, is not adding much to the
| pile.
| stickfigure wrote:
| A totally reasonable approach! Sometimes.
| nucleardog wrote:
| The interface in question is `IConfigurationFileService`. I
| can only guess at the actual interface, but based on the
| name it doesn't sound like it's abstracting away the need
| to put your configuration into files.
|
| Could just be a case of bad naming and it solves everything
| you're saying. But it sounds like pointless enterprise-y
| fuckery to me.
|
| I would not say the same thing about
| `ConfigurationFileService : IConfigurationLoader` or
| something.
| xnorswap wrote:
| Perhaps a better example is a real world example I ran into
| just this week.
|
| I found out that our unit test suite would only pass when run
| under elevated credentials. Our internal developer tooling
| had been running under semi-privileged credentials for years,
| and was the usual way of triggering a full unit test suite
| run, so no-one really noticed that it didn't work when run at
| a lower elevation.
|
| When run from a lower privilege, a unit test was failing
| because it was failing to write to a registry key. I first
| double checked that I wasn't accidentally triggering
| integration tests, or that the test should be tagged
| integration.
|
| But no, we had simply failed to abstract away our registry
| writes within that service. Of course no unit test should be
| writing to the real registry, but this settings manager was
| just being new'ed up as a concrete class, and there was no
| interface for it, and so it was just naively making registry
| edits.
|
| This settings class wrote directly to the windows registry as
| it's data-store wasn't noticed as an issue for years, because
| all the times it had previously been run, it had been under
| credentials which could access that registry key.
|
| And yes, there are different ways we could have mocked it,
| but favouring a concrete class meant this registry edit was
| happening unnoticed across all our unit test runs. And I
| suspect this might have been behind some of the dreaded flaky
| test syndrome, "I just tweaked a CSS file, why did my PR
| build fail?". Because 99% of times it was fast enough that it
| didn't cause issues, but with just the right concurrency of
| test execution, and you'd have a problem that wouldn't show
| up in any meaningful error message, just a failed test "for
| no reason".
|
| Why shouldn't unit tests read real-world files? Because that
| introduces brittleness, and an inherent link between tests.
| If you want fast and easy to parallelize tests they need to
| have no real-world effects.
|
| A test suite which is effectively pure can be executed orders
| of magnitude more quickly, and more reliably, than one which
| depends on: - Files - DateTime.Now
| (Anywhere in your code. A DateTimeFactory which you can mock
| might sound ridiculous, but it's perhaps the best thing you
| can do for your code if your current code / tests run on real
| dateTimes. Even for production code, having a DateTimeFactory
| can be really helpful for relieving some timing issues. )
| - Databases ( This is more "obvious", but still needs to be
| said! )
|
| And so on. A unit test suite should boil down to essentially
| pure statements. Given inputs A,B,C, when applying functions
| f, g, h, then we expect results h(g(f(A,B,C))) to be X.
|
| This can also be the difference between a test taking <1ms
| and taking <10ms.
|
| As a final point, you're usually not wanting to "test the
| code that uses a config file", you want to test code which
| you don't care if it uses a config file.
|
| The "Code that uses a config file" should be your
| Configurator class. What you actually want to test is some
| service which actually produces useful output, and that
| contains business logic.
|
| Yes, "separation of concerns" can be taken too far, but
| having something else responsible for the manner in which
| your service is configured so that your service can just take
| in a business-domain relevant typed settings object is
| helpful.
|
| As I've said elsewhere, config is actually a terrible
| example, because it's essentially a solved problem, MS
| released System.Configuration.ConfigurationManager ( https://
| www.nuget.org/packages/system.configuration.configur... ),
| and you should probably use it.
|
| If you're not using that, you ought to have a good excuse.
| "Legacy" is the usual one of course.
| shagie wrote:
| > DateTime.Now
|
| I've got this in several places.
|
| I have code that needs to check if other date is within two
| weeks of today. I have test data.
|
| I could either modify the test data based on today's date
| (adding _other_ logic to tests that itself could be
| faulty), do something while loading the test data... or
| have the date to be used for comparisons be injected in.
|
| That date is July 1, 2018. It was selected so that I didn't
| have difficulty with reasoning about the test data and "is
| this a leap year?" or across a year boundary on January 1.
|
| Its not a "I don't trust it to work across those
| conditions" but rather a "it is easier to reason about what
| is 60 days before or after July 1 than 60 days before or
| after January 1.
|
| And returning to the point - injectable dates for "now" are
| very useful. Repeatable and reasonable tests save time.
| FrustratedMonky wrote:
| The thing that should be tested is whatever you are handing to
| a client app to use. If it is an interface, then test the
| interface, not the file behind it. If the client will get the
| file, then test that the file is correct.
|
| So in this case, is this entire file being handed to clients to
| do what they will with it? Does that make sense as an
| interface.
|
| If you are building an app, and you want other parts of the
| app, or clients of the app, to use this data, does it make
| sense to just hand over the entire file as the interface.
|
| Basically :
|
| Programmer 1: "Hey man, show me your data interface so I can
| build a quick lookup on something"
|
| Programmer 2: "here is the whole damn file, do whatever you
| want and leave me alone. Figure it out yourself, and no I'm not
| going to give you a schema and I'll change it whenever I want".
| sigseg1v wrote:
| You are right. I read their posts as the ramblings of someone
| who is currently in shock, found a bunch of bad practices in
| the logging + data retention, and is now just tongue-in-cheek
| mocking (the puns...) everything even if they don't have much
| experience with it. I would probably say something similarly
| incorrect if I found some perl and tried to understand it
| because I know nothing about writing maintainable perl.
| dylan604 wrote:
| > maintainable perl
|
| isn't that an oxymoron?
| cruffle_duffle wrote:
| I am lost is that a code comment or the author commenting on
| something they found?
|
| Because I always enjoy leaked code comments. It's like "tell me
| how you really feel about this shitty bloated enterprise
| framework you are using".
|
| There were some good ones in the leaked windows source code,
| weren't there?
| robrtsql wrote:
| That's the author commenting on something that they found.
| PyWoody wrote:
| I'm sure you've seen this, but "The Simpsons Hit & Run Source
| Code Comments, Read by Comic Book Guy"
| (https://www.youtube.com/watch?v=R_b2B5tKBUM) is an all-
| timer.
| aidenn0 wrote:
| If you need to make your code more baroque and harder to
| understand in order to unit-test it, that seems like the tail
| wagging the dog.
| mempko wrote:
| Exactly! It's like that Skinner Simpsons meme. Are unit tests
| the problem and I'm wasting my time? No, it's the config
| files that are wrong.
| consteval wrote:
| > more baroque and harder to understand
|
| I don't understand how this is the case. If anything, an
| interface is MUCH easier to understand than a variety of
| functions strung together.
|
| I mean, this is the whole reason we have APIs. If I'm a
| consumer, I would much rather read and understand the API and
| its contract than try to read through the code to find out
| requirements.
| burnte wrote:
| > I know it's cool to "hate" on OO, but "just read the fucking
| file" doesn't work if you want to run your unit tests without
| reading a fucking file.
|
| Then don't do that, if in the real world it'll read a fucking
| file, then test with reading a fucking file. Tests aren't there
| to just be passed, they're to catch problems and if they're not
| testing the same workflows that the code will see IRL then the
| test is flawed. The first test should be reading a fucking file
| and that fucking file could be full of all sorts of garbage.
|
| Same goes for non-fucking files.
| xnorswap wrote:
| Those are integration tests. Integration tests are great, but
| not when you want to run thousands of them in a few minutes.
| And not when you want to have lots running in parallel,
| accessing and potentially making "changes" to the same files.
|
| I'm happy to have a long running integration test suite that
| runs on a build server.
|
| But while working on a project, I need fast running unit
| tests that I can edit and run to get fast feedback on my
| work. I find that "time to iterate" is key to effective and
| enjoyable development. That's why hot module reloading is an
| amazing innovation for the front-end. The back-end equivalent
| is quickly running affected unit tests.
|
| So I'd rather unit test my FooFileReader to make sure it can
| read parse (or not) what's in various files, and unit test my
| service which consumes the output of my FooFileReader by
| either parameterising the FooFile result or having an
| IFooFileReader injected. ( Either works to separate concerns.
| )
|
| While unit testing, I'm going to test "given that
| System.IO.File can read a file", and write tests accordingly.
| I don't want a test sometimes fails because "read errors can
| happen IRL". That doesn't help test my business logic.
|
| I can even test what happens if read failures do happen,
| because I can mock my mock IFooFileReader to return a
| FileNotFoundException or any other exception. I'd rather not
| have to force a real-world scenario where I'm getting such an
| error.
|
| In a functional world, it's the difference between:
| function string -> result
|
| and function string -> parsedType -> result
|
| The second is cleaner and neater, and you can separately
| test: function string -> parsedType
| function parsedType -> result
|
| The second is more testable, at the cost of being more
| indirect.
|
| Interfaces and factories are just an idiomatic .NET way of
| doing this indirection over services and classes.
|
| Of course you can also write more in a functional style, and
| there are times and places to do that too.
| consp wrote:
| Unit test are nice to have if you want to make test
| coverage or have sufficient time to implement them
| properly. In practice they contain only vague assumptions
| (the test passes, but the integration stops due to those
| assumptions being false) or contain things any basic code
| review should catch (and if you keep paying peanuts they
| won't do that so you make more unit tests).
| jessekv wrote:
| A good interface is testable, this is how you build up
| reliable abstractions to solve higher level problems. The
| devs on my team that take shortcuts here waste more time
| in the end.
|
| There is no cost trade-off.
| miningape wrote:
| In most cases especially for important code paths I
| agree.
|
| There is a case where I think it is justifiable to not
| write a single test: Startups. Specifically pre-seed &
| seed round funded I think are allowed to skip the
| majority of tests - however critical paths, especially
| those that are important to customers (i.e. transactions)
| must be tested.
|
| By the time you have built out that mvp and have a few
| customers then you should transition to writing more
| tests. And as the number of engineers, scope, or
| complexity grows you need to add tests.
| CamperBob2 wrote:
| It's testable right up until the point where it's
| asynchronously interactive.
|
| Would unit tests have avoided the Therac-25 incident?
| wtallis wrote:
| > While unit testing, I'm going to test "given that
| System.IO.File can read a file", and write tests
| accordingly. I don't want a test sometimes fails because
| "read errors can happen IRL".
|
| That sounds pretty squarely in the "you ain't gonna need
| it" category. If your test harness cannot make a temporary
| directory and populate it with a copy of the test config
| file that's stored in the same SCM repo as the test case
| code, then you simply have a broken CI server. There's no
| need to complicate your codebase and make your tests less
| realistic all to avoid hypothetical problems that would
| almost certainly break your test suite before the test case
| gets around to attempting an fopen. Just read the damn
| file.
|
| There _are_ more complicated instances where mocking and
| dependency injection is needed. "fopen might fail on the
| CI server" usually isn't one of them.
| miningape wrote:
| You're mixing definitions - integration tests concern
| testing the "integration" between all parts of a solution.
| It has nothing to do with reading a JSON file, its
| perfectly acceptable to read from a JSON file and use its
| data in a unit test.
|
| Also reading / parsing a JSON file is fast enough for hot
| reloads / auto rerunning unless you have multiple GB files
| - so the argument for speed makes no sense. I'd argue it's
| slower as a whole to have to code up mocks and fill in the
| data than copy paste some json.
|
| I do agree with the second being neater, however past a
| certain point of enterprise coding it's a negligible
| difference compared to the overall complexity of the code -
| so taking a shortcut and making your tests simpler through
| JSON files actually ends up being the cleaner / neater
| solution.
|
| >While unit testing, I'm going to test "given that
| System.IO.File can read a file", and write tests
| accordingly. I don't want a test sometimes fails because
| "read errors can happen IRL". That doesn't help test my
| business logic.
|
| Since you're given that - use it. If your test fails
| because a "low level" dependency is failing it's indicating
| something is seriously fucked up on your machine.
| Izkata wrote:
| It's an absurdly common mistake though, on the level of
| hungarian notation being misused and having to split it
| into two names.
|
| Basically too many unit testing tutorials were simplified
| too far, so the vast majority of people think a "unit" is
| syntactic rather than semantic. Like, a single function
| rather than a single action.
| rbanffy wrote:
| > And not when you want to have lots running in parallel,
| accessing and potentially making "changes" to the same
| files.
|
| Reading a file is a fast operation these days. Re-reading a
| file shortly after a read is less than a memory copy.
|
| Making the structure more complicated so that you can avoid
| reading a file during unit tests is a poor investment of
| resources - that complexity will haunt down the team
| forever.
| neonsunset wrote:
| The vast majority of codebases that spam factories are
| misusing the pattern and simply add more boilerplate and
| abstraction bloat for something that is easily expressible
| in true idiomatic C# itself.
|
| You see it everywhere where someone handrolls a
| "ServiceResolver" or "DtoMapper" that wrap what DI or ORM
| already handle on your behalf, simply because it is
| consistent with ancient badly written code that originates
| from practices that came from heavier Java and before that
| C++ codebases.
| jessekv wrote:
| Yeah modeless software is one honking great idea. (RIP Larry
| Tesler)
| scrapcode wrote:
| Yeah, that's called a fucking integration test.
| miningape wrote:
| > Tests aren't there to just be passed, they're to catch
| problems
|
| So many developers don't understand this simple concept - it
| manifests in 2 ways: 1. Not writing tests 2. Writing too many
| / too specific tests
|
| Testing should always be focussed on the OUTCOMES never the
| implementation. That's why they're so good for making sure
| edge cases are covered - since we are able to assert the
| input and expected outcome of the code. I like to use the
| mental image that in an ideal world I could put the same
| tests on a completely separate implementation and it would
| still pass (mocks/stubs, and implementation specific tests
| don't pass this).
|
| I'm always far more frustrated by 2 than by 1 - since 2 adds
| so much unnecessary code / complexity that doesn't need to be
| there, growing technical debt through the tool that should
| help us manage it. They make changing implementations
| painful. And worst of all they think they're doing something
| correctly and when combined with the sunk-cost fallacy
| they're incredibly resistant to changing these fucked up
| tests.
|
| Don't get me wrong 1 is annoying too but he'll at least add
| the tests when you ask him to and not over engineer
| everything.
| IggleSniggle wrote:
| There's a lot of room for nuance. If you "just read the
| fucking file" but the file isn't a "real" configuration
| file then isn't it just a "mock?" If you replace all
| network calls with an interceptor that forwards all calls
| and responses, and just check what's happening as a
| "listener," aren't you mocking out the network calls to a
| non-real implementation?
|
| At the end of the day, tests are _necessarily_ a mock-up of
| what 's real. You just happen to disagree with where some
| people put the abstraction layer. I also would like to make
| my tests more "real" but I have a lot of sympathy for folks
| that are trying to test something smaller without involving
| eg a file. After all, the whole point of "everything is a
| file" in Unix is that we shouldn't need to worry about this
| detail, it's an OS concern. If you write to a file that's
| not actually a file on disk but actually a device, that it
| should fundamentally be okay and work as expected.
| miningape wrote:
| Yeah don't get me wrong, I'm not anti-mock - real code is
| messy, and the ideal of the same tests running everywhere
| will never work, so mocks are necessary. But I do think
| there's a lot more harm from over-mocking, than under-
| mocking.
|
| > file isn't a "real" configuration file then isn't it
| just a "mock?"
|
| I want to say "no" but I haven't thought about it enough
| yet. My reasoning is that the file itself contains
| information about the expected messages to/from systems,
| since it _is_ the body of whatever the system should
| respond to. And while it is only 1 layer separated from
| just creating the same object in memory for your test
| this "feels" different because you can't just pull it
| out of your codebase into curl.
| IggleSniggle wrote:
| Just to work this out together a little more in
| discussion form, since I appreciate your attitude:
|
| Consider these two scenarios:
|
| - read "test1-config.json" from disk, into whatever most
| easy JSON-adjacent format makes sense for your lang
|
| - just use the JSON-adjacent format directly
|
| Isn't the difference between these that one requires
| coupling input configuration of the environment to the
| tests (possibly inclusive of env vars and OS concerns
| around file I/o), making running the tests more
| confusing/complicated in aggregate, while the other
| requires coupling input configuration to the tests,
| making the unit under test clearer but potentially less
| reflective of the overall system?
|
| Effectively this is just an argument between integration
| tests and unit tests. Unit testers certainly have the
| rhetorical upper hand here, but I think the grug-brained
| developers among us feel that "the whole program should
| be a pure function."
|
| That can ultimately be reduced to a P-NP problem.
| miningape wrote:
| yeah - I don't think we should go so far as to write a
| config file for a test. But if we have something that is
| already readily convertible to/from json, it should be
| used. Not seeing it so much as a config for a test but as
| an argument we're storing in a separate file.
|
| For example if we had a dto that serialises to/from json
| we should be storing json not creating this dto manually
| - I would push it further and say any structure which is
| also easily/transformed from json, like extracting a
| certain property and using that in the test (although
| this is also context dependant, for example: if there are
| other tests using this same file). As a counter example I
| wouldn't advocate for using json config files to test
| something completely unrelated to an underlying json
| structure.
|
| > That can ultimately be reduced to a P-NP problem
|
| Yeah ideally the goal should be to write the simplest
| code possible, however we get there - shoehorning an
| approach is always going to add complexity. I think
| there's a lot of danger from taking rhetoric too far,
| sometimes we push an abstraction to its limits, when
| what's really required is a new perspective that works
| well at these limits.
|
| Effectively I think there's a range in which any argument
| is applicable, its a matter of assessing if the range is
| large enough, the rules simple enough, and it solves the
| actual problem at hand.
| Izkata wrote:
| > yeah - I don't think we should go so far as to write a
| config file for a test. But if we have something that is
| already readily convertible to/from json, it should be
| used. Not seeing it so much as a config for a test but as
| an argument we're storing in a separate file.
|
| This sounds like a great candidate for the facade
| pattern: https://en.m.wikipedia.org/wiki/Facade_pattern
|
| Basically you hide dependencies behind a small interface,
| which lets you swap out implementations more easily. The
| facade is also part of your codebase rather than an
| external API, so it gives you something stable to mock.
| Rather than a building facade like the name is based on,
| I think of these as a stable foundation of things a
| module calls out to. Like your code is a box with an
| interface on one side (what tests and the rest of the
| codebase interact with) and the facade(s) are on the
| other side (dependencies/mocks of dependencies).
| qwertycrackers wrote:
| Your unit tests should just take the result of loading the file
| as an argument or other type of injection param. Then you can
| hardcode your unit test config parameters in the test code
| itself. That's the appropriate place for this kind of
| indirection.
| ChicagoDave wrote:
| I worked at RedBox in 2010. C# with embedded Lua for the screens.
| The intent was to build a flexible architecture for CoinStar to
| use on many kiosk businesses.
|
| The PII is likely log files that should have been erased nightly,
| but I don't remember.
|
| I know the guy that designed the architecture. He's a friend that
| I've argued with about over-engineering things. He never cared if
| people understood his work, which is a common theme with old
| school engineering.
| danielmg wrote:
| It's not just an 'old school' thing. FFS look at the state of
| the Javascript ecosystem.
| ChicagoDave wrote:
| There certainly are spots of over-engineered solutions in
| today's world, but overall I do believe things like cloud
| serverless, and domain-driven design (modularization) have
| reduced complexity in a natural fashion.
|
| These over-engineered systems usually came out of client
| server architectures using heavy inheritance object pyramids,
| which we definitely don't build as much anymore.
| JoachimS wrote:
| Not an old school engineering. There a fresh engineers rolling
| of the production line everyday that behaves exactly like this.
|
| I would even venture to say that senior engineers are probably
| much better at documenting, writing clean code, not over
| engineer things. My personal experience is that bad engineers
| move into project management, administration much faster. Which
| is a problem in itself since they end up being the boss of the
| engineers that are better than what they are.
| Jach wrote:
| I agree on the management aspect, and even promoting good
| engineers "too high" on the "parallel promotion track" can
| effectively take them out of the engineering work just as
| much as if they went into pure management. "Does the CTO
| still code at least sometimes?" is the only tell I have for
| whether a company has fallen into that trap or not.
|
| For the engineers themselves, though, I think it's a mixed
| bag when it comes to "older" ones. That is, correlations on
| just age in the field are weak. Sometimes they're great,
| sometimes they're really meh. Whether something is over-
| engineered or not really is case-by-case, part of the problem
| is sometimes something looks over-engineered but is just the
| normal thing to them by now, nothing special, even though its
| architecture handles a lot of concerns that a more naive and
| obviously not over engineered style would have produced. In
| that case, they're validated sooner or later.
|
| Sometimes they're more up to date about various new things
| than even the energetic young bucks, sometimes they're too
| stuck in their ways. I've seen examples of both knowing about
| modern hardware details (and being able to take advantage of
| them) and having a stale idea of how CPUs work that wasn't
| even quite accurate in the 70s. (So, not too different from a
| lot of fresh engineers who get educated on such simple
| models.) I've noticed no correlation with age on whether
| someone has completely mistaken ideas about JVM performance.
|
| Being stuck in their ways in particular applies to things
| beyond the pure code and coding style -- and it's not
| necessarily a bad thing. If they've managed well so far
| without pick-any-of good documentation, good debuggers, good
| source control, good editors, good open source, methods to
| thoroughly avoid various causes of engineering pain, etc.,
| why bother doing or taking advantage of those things now? And
| if they're skilled, they might even be right, it's probably
| best not to disrupt them if they're not a bus factor risk.
| But if they're more on the meh side of things overall, they
| can hold things back too much.
|
| (By "older", I mostly mean those who were practicing since
| the late 90s/early 2000s. But I keep in mind that the global
| supply doubles every several years or so, so it's quite
| possible for someone with only around 5 years of experience
| to be in the top half of seniority already.)
| neilv wrote:
| > _He never cared if people understood his work, which is a
| common theme with old school engineering._
|
| Not in my experience.
| gU9x3u8XmQNG wrote:
| I once worked for an MSP that would reuse decommissioned storage
| for other customers and services.
|
| Tried to convince them to stop, and even setup a service on lunch
| breaks to attempt and sanitise them using open guidelines
| available at that time - an automated service that would display
| drive sanitisation status on a text based panel next to a multi
| disk bay caddy in the storage room.
|
| I resigned because of this, and many other similar business
| practices - all just to make more money (it was not malicious
| otherwise).
|
| The business is rather successful to this day. I only hope they
| have stopped such activities.
|
| And yet I still lose sleep about this..
| nihilist_t21 wrote:
| Ahh I miss Foone's threads on Twitter/X!!! They were always such
| an interesting joy to read. I know they migrated off of Twitter/X
| and they were one of the ones I was most sad to see leave. But
| given 95-99% of the accounts I follow never left, I'm not going
| to bother to cultivate another social media account just for
| Foone's threads, or whomever else's which I've forgotten left
| Twitter/X.
| th0ma5 wrote:
| I am so glad people are leaving Twitter even if they don't do
| anything else, and maybe especially lol
| patrickhogan1 wrote:
| Thats terrible. User doesn't say how they got the machine. Maybe
| a bankruptcy liquidation auction.
|
| Sidenote: As a personal mental quirk, does anyone else ever
| accidentally read "Redbox" as "Roblox" and then have to double-
| check?
| Alupis wrote:
| As an aside, I see we've re-invented Twitter-style blog posts -
| but did anyone stop and ask why?
|
| This format is so tedious to read - one sentence fragment at a
| time. It's like reading someone's subconscious inner-dialog
| shower thoughts.
| th0ma5 wrote:
| Sort of the other way, many social networks had longer formats
| and Twitter eventually adopted it. On twitter it actually never
| quite made sense but on fedi stuff it works a lot better.
___________________________________________________________________
(page generated 2024-10-16 23:01 UTC)