Code
I love Terraform but, as we’re fond of saying at work, “it’s a loaded gun pointed at your production environment.” There are ways to minimize the risk but they boil down to writing a bunch of test automation around Terraform so as to be sure that it’s not doing something evil.
That’s a great idea, but no one much wants to pay for it. Toil budgets would be a great way to get buy in on this, but that’s another topic for another day.
This means that while I can easily spin up all kinds of expensive cloud resources just by running a Jenkins job, it’s easy to lose track of them and forget to spin them down. This then leads to an annoying hunt through a bunch of Jenkins console output panes trying to find environments with weird names like “trusting-manatee” and “polite-tick”
So, since I’m not allowed to have a script to clean up environments, I wrote one to find the jobs I need to promote in order to clean up environments. Hooray!
SEARCH_STRING = "lost-environment"
Jenkins.instance.getAllItems(AbstractItem.class).each {
if(it instanceof hudson.model.FreeStyleProject) {
for (build in it.builds) {
def log = build.log
if (log.contains(SEARCH_STRING)) {
println "${it.getFullName()}: ${build.id}"
}
}
}
}
Is it fast? No. Is it elegant? No. Does it work? You bet.
This is less of a blog post and more of a brief public service announcement. Â If you are using Entity Framework and you change the namespace of your Context file bad things will happen. Â Future Add-Migration commands will attempt to re-script your entire database. Â Google will be remarkably unhelpful in diagnosing this problem.
“But,” you say, in your best Comic-Book-Guy voice, “changing namespaces is annoying; no one would just change their Context’s namespace.” Â To which I reply, “if you’re using ReSharper you might, because it pretty much automates the process and nags you if you move files around.”
Not that solving that problem just consumed an hour of my day or anything.
One of the projects I have been working on with VirPack has been the establishment of a developer’s training program and central to that program has been Robert Martin’s materials on Clean Code. Â While many of Martin’s ideas have sparked some interesting discussions at VirPack, none has been more controversial than his discussion of Test Driven Development. Â Martin holds to a three-part cycle: Fail, Pass, Re-factor – in which you write just enough of a test to fail, just enough code to pass, and sometimes re-factor to clean up before cycling back to failure. Â This results in a number of areas, particularly in Martin’s examples, where tests seem to be written merely to justify an action everyone agreed was necessary in the first place — say, a test to see if you can construct an object which is then run, and fails, because the object does not yet exist.
While I am pretty well sold on Martin’s coding philosophy I decided to take my coworkers objections under advisement but with a grain of salt. Â Most of the Kata and examples that Martin works through are very simple; they have to be in order to be short enough and accessible enough to communicate the points he is trying to make about software development but that simplicity also means that the early fixed-costs of TDD seem very big compared to the actual “meat” of the problem he is trying to solve.
So I set out to try out true TDD on a project which I knew was going to be complicated. Â Martin’s examples of things like a bowling score calculator had just a few plausible test cases and a mere handful of interesting results which could emerge from a complete examination of all possible execution paths. Â I wanted something much bigger and much more complicated and the historian in me knew just where to look. (more…)
Inversion of Control (IOC) frameworks have become quite the rage as the software craftmanship movement has gathered steam. IOC makes it much easier to break complex multi-part programs into distict, and more importantly testable, components so that they can then be glued back together at run time. There are lots of nifty frameworks that can make this happen but at the moment I’m playing with Ninject.
Ninject is a very minimalistic IOC framework which focuses on what it calls a “fluent interface” that leverages the compiler and IDE rather than a huge XML file to map dependencies. Overall it’s very fast, very light weight, and very powerful. I’ve picked it up quickly and found it to meet almost all of my IOC needs.
Save one. And this is apparently a big problem for a lot of people. Ninject doesn’t like overloaded constructors. (more…)
My first real exposure to databases was with MySQL. Â Every database has its ups and downs and MySQL is no exception, but among its major ups was – to me anyway – a function called Group_Concat.
If you’re not familiar with Group_Concat, consider a basic role based security system. Â You have numerous users, each of which has has one or more roles. Â It is easy enough to get back a list of user/role pairs, easy enough to get back a list of roles with one user per role, and easy enough to get back a list of users with one role per user; that’s all basic join syntax.
But what if you want a list of roles — one row per role — and want to know every user that has that role?
That’s what Group_Concat is for. Â Bicker and argue all you like about why one might or might not need this functionality, there are just times when it’s nice to have.
Unfortunately, MS-SQL doesn’t really implement it… or it didn’t. Â Recently I found a sort of hacked together implementation of Group_Concat in MS-SQL that actually works. Â Since I’m developing in C# these days, the following implementation applies to a SQL 2008 database implementing ASP.net’s standard role based security.
SELECT RoleName, UserNames FROM dbo.aspnet_Roles AS r CROSS APPLY ( SELECT u.UserName + ',' FROM dbo.aspnet_Users u INNER JOIN dbo.aspnet_UsersInRoles uir ON u.UserId = uir.UserId INNER JOIN dbo.aspnet_Roles rr ON rr.RoleId = uir.RoleId WHERE r.RoleId = uir.RoleId FOR XML PATH('') ) D(UserNames) GROUP BY RoleName, UserNames
The relevant parts of this are the XML cleverness and the CROSS APPLY, everything else is basic SQL.
The XML bit relies on MS-SQL’s XML support and is, bluntly, a hack. You can play with it independently with queries like this one
SELECT UserName + '' FROM dbo.aspnet_Users FOR XML PATH('')
Long story short, adding that FOR XML PATH(”) to the query results in instant concatenation of values. So now all that’s left is to properly relate this to the outer query. That’s where the CROSS APPLY comes in. CROSS APPLY allows you to specify what amounts to a derived table that can legally contain references to some outer information, in this case our outer query. That’s necessary to constrain our inner table so as to only get the users we are interested in. We can’t do it outside of the CROSS APPLY because, by then the concatenation has already occurred.
User controls are the source of a lot of headaches in C#. They have two major issues that tend to drive programmers a little mad. The first is that they don’t play nicely with the ViewState. Particularly once users start to nest and reorder user controls, the ViewState model (much of which is based on position within the page) starts to break down. In many cases programmers circumvent this little nightmare by simply disabling the ViewState on some controls.
The second issue is that user controls are in their own scope and don’t have immediate access to the rest of the page. That is both a blessing and a curse; good control design means that the controls should be fairly independent of each other but a more pragmatic developer will also note that user controls exist primarily so that numerous copies of the same thing can be easily created and that making entirely self contained controls leads to a lot of unnecessary duplication.
Fortunately there are workarounds for both of these issues. (more…)
VirPack has me working on an application that needs a user administered list of options for people to choose from. It’s a fairly simple thing that doesn’t require relational tables so I thought I’d toss it into XML.
Now, C# deals with XML really well. Almost everything, if you just ask nicely, will be quickly and easily packed off into XML the framework with just a few lines of code.
Unit testing is good; test driven development is better. As Knuth once famously quipped “Beware of the above code. I have only proven it correct, not tested it.” There really is no substitution for good, solid testing.
Unfortunately, at least in C#, webpages don’t like to be unit tested. I approach this post with an uncomfortable realization that I am about to lay out the issues and problems I’ve had while the solution I am presently using is far from satisfactory. (more…)
My “learn C# project” at work has centered around creating a drag-and-drop portlet style system for the display of custom widgets. I’ve been using JQuery UI for the javascript functionality but the backend has been all custom C# work.
People familiar with C# know that C# supports the inclusion of user defined controls called WebControls. These are more or less very simple C# programs which can be man-handled by another bit of C# code. They’re handy for making your code modular: you might design a web-control that takes and validates a credit card number, for example.
But WebControls are notoriously tricky beasts and over the course of the last few weeks I’ve come to understand that one of the reasons for this is that they don’t behave quite the way you might expect them to when they are serialized and deserialized. (more…)
It is time for Nephandus to change… again.
I registered Nephandus.com when I was in college. Since then it has been a flat HTML page, a Macromedia (now Adobe) Flash application, a custom PHP driven web-application, a PHP/Fusebox web application, and a Zend PHP web application. In that time I’ve gone from being a student of History at the University of Virginia to a software developer at VirPack in Blacksburg, VA with stops along the way at Radford University (it turns out no one will pay you to have just one degree in History), Fingertip Marketing, BearingPoint, Sitevision, and Coral Networks. (more…)