Configuration Switches

Recently, we were running into Out Of Memory issues with our software. A developer had identified that a feature which launched an embedded browser was using up quite a bit of memory, and we could move it into a separate process which would have its own memory allocation.

We followed his recommendation, so we moved the browser into a separate process and released this software (which I will denote “V1”). This caused an issue because the dll wasn’t built with the correct settings. We needed a quick fix due to the number of complaints from our users. It would be easy to fix, but due to the Testers stating it would take a few days to test it again, the managers told us to simply revert it and give the users the memory issues again (so this is “V2”).

We then fixed it, but since we had more time, we decided to implement a configuration switch so that if it went wrong, we could just disable it without having to release a new version. I made a small refactoring to get the configuration switch working, but I made a small mistake in the constructor which caused a crash in one of the places where the browser is launched. A Tester had found it late in his testing. I came up with a fix, but then we got called into a meeting to discuss what we needed to do. Unfortunately, my new fix would require a lot of the testing to be redone. The “refactoring” I did was brought up for discussion, and an experienced developer said that my way of doing it wasn’t the way he imagined. All the managers on the call trusted his judgement and felt I had gone a bit overboard, so they insisted I redo it.

So I had another look and couldn’t see how I could possibly do it without refactoring at least slightly. I did the best I could which I’d say was actually ~90% identical, apart from it was clearly worse from a code-design perspective. I showed it to the experienced developer and he said that was how he imagined it. I was baffled, but this is what the managers asked for. The release got delayed a week because the tester had to retest everything. So in the end, we had just wasted days of time to make the code worse. Brilliant. If we had gone with my original fix, it would have taken the same amount of time, but the code would be better.

Additionally, we did highlight we couldn’t test all the third-party suppliers we integrate with, so we had “low confidence”… or there’s some uncertainty at least. However, the Directors got involved and they wanted it out. So out goes “V3”.

There was a problem with just one of the third-party suppliers, but for some reason, Support left the feature enabled for several hours, when they could have reverted it with my Config Switch. This led to many complaints (yet again), and therefore panic from the management. When it came to disabling it, despite being able to disable it for particular users, they turned it off for large groups.

We rollout our changes in phases, so the Software Delivery managers wanted me to rollback the changes once more before releasing to the next group of users. I asked why we couldn’t just use the Configuration Switch, and the response I got was “we don’t trust Deployment to turn the feature off. What if they miss some users?

Well, when those users complain, you just switch the Configuration Switch to “off”. If we rollback again, then we are back to square one; where users can encounter the memory issue.

What is the point in coding a Configuration Switch if they won’t use it? I did point out the way the Configuration Tool works is that you could set the configuration ahead of time (the previous software version will just ignore the extra config), then when the users get the new version, then the updated version would use the configuration file as intended. So with a bit of persuasion, that’s the option they went for. However, they turned it off for every user, even if it wouldn’t have caused problems for them. 

When will they turn it back on?

Conclusion

It was actually a good idea to use a Configuration Switch. If the feature doesn’t work properly, you can quickly revert to the old way (well assuming your new changes don’t unintentionally break the existing feature). Obviously, you need to trust the Deployment team to actually use it correctly.

Colin went with a Configuration Switch for his recent project. How did he get on?

“The bug can’t be introduced by our project because it is switched off on live”.
5 mins later…
“This is definitely code that we changed”

Colin

Final Inspiration To Create This Blog

I noticed a folder in Outlook called Conversation History that has a log of all my conversations from when we used Skype. It’s a proper treasure trove of banter and funny stories. I’ll definitely be posting some of these conversations in the future.

I found this conversation pretty interesting. It’s from 6th February 2019. I checked the date when I started this blog. 6th February 2019

The Skype conversation starts off with me pasting in comments from a Code Review. Colin had fixed a minor issue, but hadn’t added a new Unit Test for this scenario. I had flagged him up on it.

I was ranting to a colleague about Colin’s response. Colin had thought I was asking if the existing unit tests have been run, rather than me asking him to write new tests for the new functionality.

Me 13:22:

         Me
         unit tests?
         Colin
         Not failing
 
 
oh that's ok then. Just fix a bug and don't cover the missing scenario
WHY DO I WORK HERE?

Colleague 13:22:
Why would you not write one??

Me 13:22:
it may fail if you write one

Colleague 13:23:
Lol
 
Me 13:27:
I might write a book on my programming experiences

Colleague 13:28:
Lol, I'm sure it'd be a bestseller 😛

I think I did consider the idea of starting a blog because I thought I had good stories to tell, and was ranting about stupid things my colleagues did. However, I wasn’t 100% convinced it was a good idea. It seems like my colleagues’ reply was the final motivation for writing about my experiences as a software developer. 2 years on, and I am still enjoying ranting, and feel I have plenty more stories to share.

C# Casting Nonsense

Introduction

I briefly mentioned the data types int (aka Int32) and long (aka Int64) in a previous blog Integer Overflow – Zaccaria Pinball. A key point is that the maximum value of an “Int32” type is 2,147,483,647, whereas “Int64” has a max of 9,223,372,036,854,775,807.

This blog is going to be more nerdy than my usual ramblings. It’s going to cover some C# code. In this blog, I’m going to show some interesting things that happen with Casting. Casting is defined by

A cast is a way of explicitly informing the compiler that you intend to make the conversion and that you are aware that data loss might occur, or the cast may fail at runtime.

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/casting-and-type-conversions

Simple Casts

Casting is done by putting the datatype in brackets next to the variable. Let’s see that in action.

We can begin with an Int32 (I’ll call my variable “anInt32”). Then on the next line, I will cast it to an Int64.

 Int32 anInt32 = 50;
 Int64 anInt64 = (Int64)anInt32;

We can also start with an Int64 (I’ll call it “anInt64”). On the next line, I will cast to an Int32

 Int64 anInt64 = 50;
 Int32 anInt32 = (Int32)anInt64;

The number 50 can fit in either Int32 or Int64. This works just as I intended. Nothing bad happens. But let’s move onto the more interesting scenarios.

Downcasting – Dataloss

So let’s create a large number and correctly store it in a Int64. Then we try and down-cast it into an Int32. It’s isn’t going to fit, so what happens to the number?

Int64 largeInt64 = 19992244551234;
Int32 intNumber = (Int32)largeInt64;

It overflows. The number stored in the variable “intNumber” becomes -828211646 and we have a bug. This is basically what happened in the Zaccaria Pinball example. The number was simply too big to fit in the space that an Int32 allows. If you are playing a computer game, it’s better than out-right crashing, I guess.

Casting With Objects

The previous examples show you can convert between Int32 and Int64 by casting.

Instead of being very specific with your variables, you could declare variables as the base type “Object”. Despite Objects being set to a number type such as Int32 or Int64, you can only successfully cast when the type matches, otherwise it will give you a runtime error, and say the “System.InvalidCastException: Specified cast is not valid.“. It’s quite a hard thing to explain, but let’s see it in action.

We first declare a variable of type “Object”. It is implicitly an Int32. Then on the next line, we cast it to Int64. In previous examples this would be fine, but as I try to explain in the previous paragraph, declaring it as an Object seems to play by different rules. Therefore the following code throws the InvalidCastException, since the declaration was implicitly an Int32.

Object intObject = 30024;
Int64 int64cast = (Int64)intObject;

So if we declare it explicitly as an Int64, then casting from Object to Int64 does work because the underlying type was an Int64:

 Object int64Object = 30024L; //explicitly an Int64 by using the L character
 Int64 int64cast = (Int64)int64Object;

But, similarly, as we saw in the previous failed example, casting it to an Int32 results in InvalidCastException, because the type does not match.

 Object int64Object = 30024L; //explicitly an Int64 by using the L character
 Int32 intcast = (Int32)int64Object;

Very frustrating and quite confusing! Earlier in the blog, I was showing you that if the original types were declared as a proper number types (Int32 and Int64), we can cast between them. However, when it was originally declared simply as an Object, we can’t seem to do this.

Convert to the rescue

Instead of casting, we can use Convert. These examples work as intended.

Object intObject = 30024;
Int64 int64convert = Convert.ToInt64(intObject);

Object int64Object = 30024;
int intconvert = Convert.ToInt32(int64Object);

Try It Yourself

Here is the full code to easily paste into Visual Studio (or your favourite IDE) and try it yourself.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Playground
{
	class CastingNonsense
	{
		internal static void Run()
		{
			Test1();
			Test2();
			Test3();
			Test4();
			Test5();
			Test6();
			Test7();
		}

		private static void Test1()
		{
			Int32 anInt32 = 50;
			Int64 anInt64 = (Int64)anInt32;
			//fine
		}

		private static void Test2()
		{
			Int64 anInt64 = 50;
			Int32 anInt32 = (Int32)anInt64;
			//fine
		}

		private static void Test3()
		{
			Int64 largeInt64 = 19992244551234;
			Int32 intNumber = (Int32)largeInt64;
			//overflows, but doesn't crash. Number becomes -828211646
		}

		private static void Test4()
		{
			Object intObject = 30024;
			Int64 int64cast = (Int64)intObject; //InvalidCastException
		}

		private static void Test5()
		{
			Object int64Object = 30024L; //explicitly an Int64 by using the L character
			Int64 int64cast = (Int64)int64Object;
		}

		private static void Test6()
		{
			Object int64Object = 30024L; //explicitly an Int64 by using the L character
			Int32 intcast = (Int32)int64Object;
		}

		private static void Test7()
		{
			//Convert solves the problem of casting. This works fine
			Object intObject = 30024;
			Int64 int64convert = Convert.ToInt64(intObject);

			Object int64Object = 30024;
			int intconvert = Convert.ToInt32(int64Object);
		}
	}
}

Integer Overflow – Zaccaria Pinball

Zaccaria Pinball is a pinball game you can buy on Steam. User Breeze posted this screenshot of his score: 1,947,658,906. A negative score!

 What happened is that he has reached the maximum score, then it suddenly becomes negative.

I don’t know what language Zaccaria Pinball is programmed in, but in C#, the maximum value of an “int” type is 2,147,483,647. So I imagine he has surpassed the current record, then suddenly it flipped to the record low score. He must be furious.

It is important you choose the correct datatype to store data correctly. Often on pinball games, people amass some crazy scores that you don’t think are possible, so it would probably make sense to go for the “long” type which has a max of 9,223,372,036,854,775,807. Hopefully the developers change this before annoying more players.

The secret features that Google didn’t want you to know

I do love a stupid clickbait title. These features are quite hidden though.

This particular link takes you to dice rolling app which would be good for board games. If you happen to lose your dice – then Google saves the day.

Google’s “Roll dice”

To switch to the other exciting apps, you can click the chevron, then there’s two tabs, GAMES AND TOYS, and TOOLS

Games and Toys

Earth Day Quiz

Tic tac toe

Snake

Spin a dreidel

Animal Sounds

Solitaire

Pac-Main

Minesweeper

Fun facts

Tools

Flip a coin

Meditate

Colour Picker

Calculator

Metronome

Spinner

As a bonus hidden feature, I always think Ngram Viewer is interesting when you want to get a rough idea how popular certain words are. Today, a colleague used the word “banjaxed” and I thought “that’s a very archaic word”. I think I had only heard it once and that was in a song (ALESTORM – Shipwrecked). It seems Alestorm used it at the peak of popularity.

For more secrets, check out The secret Touchpad features that Microsoft didn’t want you to know

The eight factors of happiness for developers

Maybe it is a bit philosophical and pretentious but I thought it was interesting. In many ways, it is like the antithesis of Stranger Coding Tings. For example, my blog is about thinking about past grudges, and venting frustration at things I can’t change. 

Check out the full blog here:

Simply posting a link probably wouldn’t be that exciting and entice you to read it, but pasting the full article is just plagiarism – so I’ve put together a summary from the opening lines in each section as a compromise:

1. Resentment

Harboring resentment or anger toward another team member can be a significant source of unhappiness. 

2. Not living in the past

Don’t dwell on that job that you didn’t get or that project that went bad. If we live in the past, we are doomed to repeat it. As developers, we need short memories and one of the best ways we learn is through failure. 

3. Cooperate with life

The Serenity Prayer asks us to accept the things we cannot change, change the things we can, but also have the wisdom to know the difference.

4. Stay engaged with the real world

As developers, it’s easy to withdraw into our own world. It’s often a reclusive profession, and without even trying, we can have very little interaction with others. But humans are social creatures.

5. Love yourself (and others)

Programming is hard and don’t let anyone tell you it’s not. The problem is coding is a technical skill and there are rock stars and ninjas, and there is the rest of us (I’m in this camp). We must have empathy for ourselves and others as we move around in this profession.

6. Be virtuous

As engineers, we live in a highly technical environment so we think that gives us a pass on virtues like love, compassion, and empathy. 

7. Lower your expectations of yourself

Shoot for the moon, if you miss, at least you will be among the stars. We’ve all heard this a million times, but, as I said earlier, coding is hard, so I am going to propose that we cut ourselves some slack and don’t expect so much. Just by virtue of our chosen profession, we are overachievers and we make things doubly hard when we expect to progress too fast.

8. Serve something bigger than yourself

Self-centered and narcissistic people are the least happy people on the planet. The happiest people have found some balance between serving and caring for themselves and serving their family, their co-workers, and those in their community. I once heard someone describe the three pillars of human happiness as fulfilling the need for meaningful work, the need for lifelong connections, and the need to serve something bigger than yourself.

Skeletons In The Attic

I was on a call and one guy turned his webcam on. He has a full-sized skeleton behind him. He leans back in his chair and stretches. I was wondering if he was trying to “stealthily” cover it up. Shortly, he turned his webcam off. Later in the call, he turns it back on, and the skeleton was nowhere to be seen. So maybe he was trying to cover it up afterall.

Teh

I remember back in the early noughties, lolspeak became a thing which included intentionally poor grammar – so you would write “teh” instead of “the”. (There was l33tspeak too where you’d intentionally switch out letters for numbers).

I can understand making this (“teh”) typo occasionally, although most people would notice and correct it before sending. When there is a red, squiggly line under the word, then surely you are going to accept the spelling suggestion rather than ignoring it and sending the message anyway.

There is one colleague that constantly writes “teh”. I think they only correctly write “the” maybe 10% of the time. I find it infuriating. 

Maybe it is a boring blog, but I just wanted to illustrate what I have to endure:

  • Was an email sent to her around teh requirements, I know there was teh one from Rob for the first part
  • works for teh other test box
  • I restarted teh box
  • I still get teh invalid URI message in error logs so it has to be something to do with that
  • ok so teh deprecate button
  • where do you set teh trusted connection to true?
  • at least teh doc is now up to date
  • Yep missed teh bit at teh end
  • I noticed last night that teh service was down….that’s another issue that I’m unsure of teh error message is around network so thought it might have rectified on it’s own by this morning
  • this is teh deployment section where teh token is incorrect
  • PC in teh office
  • is this to do with teh last bug fix?
  • give me a sec, just logging on again to get teh message
  • and can’t link teh user
  • i get teh warning banner
  • is it a case of changing teh ID code of the user?
  • From teh list of entries i provided above is any valid entries?
  • Do we all have visibility of teh top 25?
  • Nope didn’t enter teh wrong pin
  • Always happens when I leave teh office
  • I can see teh docs on teh server
  • Currently our test system doesn’t fully bring across teh docs
  • hey guys don’t forgat that teh meeting is now
  • Is there some comms around teh powercut
  • teh watermark flashed up…doesn’t seem right
  • I would imagine it shows in teh preview

How To Make Your Team Hate You #3

I was thinking about the colleagues I’ve legitimately despised (and it’s not just my opinion), and most of them have something in common: they have either been promoted, or told they will get promoted if they prove themselves, resulting in a change of behaviour. So here is story number 3, and hopefully the last one since I don’t have any more drafted up.

The Situation

I was once on a project where I was the only software tester. Usually, when it’s a proper project where it is going to span 3 months or more, then we would have at least 2 testers assigned.

I was well excited to show that I could handle this responsibility. The project went well, and I was well proud. That project was actually a prerequisite for something bigger, and yet again, I was looking forward to the challenge of the follow-on project.

Collectively, both projects were going to be a replacement for part of our software, but it was going to be phased over time. Therefore, it was important that the old version still worked.

So I looked at what the current system did and wrote all the features down. I then spent ages looking through all the Test Cases, comparing these to the features that I documented. Then I had to write the Test Cases that were missing. This probably took around a month of preparation.

Since the new version needed to do what the old one did, but might have done it in a different way, I basically had to duplicate every test, then start changing the steps accordingly.

Having this 100% complete test coverage worked well, and I knew people would be thankful for it in the future. Anytime a feature is changed, you know there are tests that you can run for your manual regression tests. I think every tester has been annoyed at some point; when they think a test should exist, but it doesn’t, so they have to begrudgingly write it.

I’ve done the work for them. I don’t think any other area of the system had this level of test coverage. No one can be annoyed about this can they? 

As we moved onto the second project, I was told another Tester, Barbara was joining the team. I’m not sure if I was told explicitly, or if I just heard rumours, but I’m pretty sure I knew it was the case that – if Barbara did well on the project, then she would be promoted to Test Lead. Based on my performance over the years, and based on the project I had just finished, I think it should have been obvious to promote me to Test Lead. Maybe I was slightly annoyed, but I don’t think that had any affect on what happened next…

The Conflict

So Barbara joins the team and looks at the test cases. She wasn’t happy. Despite having that 100% test coverage, the tests were “too granular”. She says that when it comes to testing a particular feature, we would end up adding maybe 10-20 tests from my pack. She only wanted to run 1 or 2.

So she starts complaining at me, telling me I’ve wasted my time and I need to rewrite them. She likes the idea of “end-to-end tests” where one test actually tests several features and could describe what a user would do over a 5 minute period.

For example, I may have written a test that describes how to create a document, then another test how to print a document, then another test on how to email a document.

Her way of testing would be to include all the instructions for these 3 features and put them in one test – since a user may log in, create a document, email it to someone, then print a copy out for themselves.

I argued that my way is better, because if there is a bug involving email, you can just pick out the short test involving email. I’d be annoyed if I had to test printing it when it has nothing to do with the email bug fix.

But that’s not how we did it in my old team!

Yeah, but you aren’t in your old team. You’ve joined this one, and this is our process.

She used this statement multiple times about different aspects of how we work. I kept on explaining how if we work “agile”, we are supposed to come up with a process that suits us, and agree as a team. This process suited us, or at least it worked perfectly well before she joined our team.

Yet she comes in, kicks off a massive fuss to try and put her stamp on the team, and bypasses the correct channels for these decisions; which would have been the Retrospectives. I would have been happy to debate it in a meeting, rather than her dictating what I should do in front of everyone.

What Barbara did next was – run off to her manager, who happened to be my manager as well. But because my relationship with my manager was simply a professional one, and Barbara was very chummy with her, then our manager instantly backed Barbara.

So then I had to plan out which features made sense to use after each other. I spent 3 or 4 days planning this out. I spent more days writing them. I only wrote about 7. How many test cases did she write? 

Zero. 

Didn’t practice what she preached.

I was fuming.

When it came to testing the new features, she often volunteered to test the easier items, and gave me the harder items. I didn’t mind, because if she wasn’t on the project, I would have just done them all anyway.

What was infuriating, was that the next day, she would chat some nonsense about how she was too busy so didn’t have time to test it, so then asked me to test it instead. So I’d end up doing all the work. It’s just that it would take longer because I’d finish my work and have nothing to do, then the next day, I’d have to do her work that she was supposed to do. So the result was that we had 1 extra tester in the team, but productivity had halved.

She did this for weeks. It wasn’t a one off. Often, I’d look at her monitor and saw she was sending personal emails, doing online shopping, or just looking at news.

Then when it came to the stand-ups, where we stated to the rest of the team what we had accomplished; she then claimed that she did the work.

I was fuming. How could she say that when I was standing there with her? It’s plagiarism, and absolute lies. I complained to my manager. She refused to do anything. I was so tempted to walk out.

I’d never had that feeling of not wanting to go to work before, but some days I just didn’t want to go. I actually started looking for new jobs.

Sometimes when Barbara was away from her desk, I’d be ranting to my team. We were a close bunch on the initial project, but it just didn’t feel the same way. Soon I was brought into a meeting with the project manager who seemed to suggest I should apologise and try and get on.

I don’t get it. We were all close and worked well together. We delivered a project successfully on time. A new team member joins. Testing productivity is halved. There’s massive friction. Who do you think is the problem? You could easily verify my claim that she wasn’t doing the work. The test case runs are audited. My name would be on every one.

It seemed that Barbara had just sweet-talked everyone and they were determined to promote her regardless. As a Test Lead, you are supposed to have testing skills, people-skills and some management skills. Barbara wasn’t showing any of it. She was refusing to run test cases and she was causing friction. Productivity of the testing side was lower than when it was just me on my own.

Epilogue

So what happened in the end? Well, I was a bit unsure what I wanted in my career. I initially wanted to move up the ranks as a Tester, but it wasn’t happening. I did get the craving to be a Developer, and considered becoming an Automated Tester. I requested a change of role to a Developer since the Automated Tester role didn’t exist in the company. I’d be in the same department, but I knew I’d switch teams so would be away from Barbara. I just had to put up with another couple of months working with someone I despised. 

I did get my internal move in the end. Barbara got her undeserved promotion. Years later she got made redundant. Better late than never.

For more in the series, see: How To Make Your Team Hate You #1 and How To Make Your Team Hate You #2