Monday, June 13, 2011

Things I need to get better at

Being a jack-of-all-trades suits me.  I enjoy being able to dabble in many diverse areas of technology.  Although my knowledge is shallow in many areas it is broad.  I am a decent programmer in many languages, and I have in my short career worked with embedded device drivers and firmware, writing proprietary messaging protocols over TCP/IP sockets, stored and queried needed information on both MySQL and H2 databases, wrote XMLRPC servers, RMI servers, written JNI wrappers around C shared libraries, and many things inbetween.  In other words, I have a pretty good view of the entire technology stack.

But there are still many areas I need improving on.  Now that I am writing more java again, and I wish to be better at clojure, I need to get better at the java ecosystem.  For example:

1.  Get better at maven.  I have built a few non-trivial maven projects, including one multi-module, but a lot of maven's finer points still elude me.
2.  Javadoc commenting.  I just let Eclipse auto-fill in the params and return values, but I really should know all the markup for it.
3. Annotations.  I understand them in theory, but I've never written one (same goes for python decorators)
4. Unit testing.  Yeah yeah, being in Test, I should know JUnit or TestNG like the back of my hand.  While I realize their importance, sadly, time constraints often win.  I have tried writing some TestNG unit tests, but they are not being called from maven, and I haven't had time to figure out why
5.  OSGi.  While I have written two eclipse plugins, I still don't truly understand a lot of OSGi.  I understand what it's for (modularity to decrease coupling, and provide metadata to end jar hell), but it's such a huge beast that I need to know more


There's also a lot in general that I want to get better at or relearn:

1. C/C++.  I haven't seriously written any C or C++ in a little over a year when I was doing some JNI wrapping.  The new features in C++0x looks interesting, and eventually, I hope to get back to more JNI programming.
2. Advanced python.  By this, I mean stuff like decorators, generators, continuations, and metaprogramming.  I actually think I finally understand generators (functions that yield an iterator like object), and how they can be used for continuation style programming.  I once showed a coworker how to implement "private" methods and fields in python through implementing some of the magic methods, but that's the most metaprogramming I've done.
3. Algorithm design.  After implementing a homegrown software dependency installer program, I came up on my own a depth first search algorithm that could do post-order traversal.  I didn't know it was called that until after I read the chapter on traversal algorithms in the book Python Algorithms: Mastering Basic Algorithms in the Python Language.
4. Concurrent programming:  Most of my experience with multi-threading has simply been to spawn a new thread to prevent blocking during a long running task.  Only twice have I had to share data across threads, and honestly, I'm not sure if I synchronized things right.  One reason I wanted to learn clojure was for its approach to concurrent programming (even OpenGL is massively parallel in nature).


And while all of the above will help me in the "real" world, for my own personal desire, I still want to learn OpenGL, and get better at clojure.  I also want to get better at JBoss's Netty NIO framework.  Sadly, much of my spare time is spent working for work.

Sunday, May 22, 2011

Why Test Engineers need to be good developers too

It would seem that in many organizations, "automation" has become something of a buzz word.  It's a term that makes upper level managers happy, but which often confound many, including Architects and lower level managers.

In order to achieve automation, especially on products which are GUI based (either as a thick client, or some web based mechanism), there is a tendency to want to use "capture/replay" tools.  In essence, these are tools that are designed to capture mouse and keyboard clicks, save them, and replay it later.  While this sounds great, and I am not against such a tool as part of the overall test strategy, when it is the SOLE method of testing, I am strongly against it.

I have read many sites talk about the dangers of using capture/replay tools, but they usually just harp on the difficulty of maintaining the "scripts" (the file that holds all the captured events).  If the GUI interface changes, then the script becomes useless.  While this is a valid point, it is not in my opinion the most serious shortcoming.  The most serious shortcoming is that it does not rely on any knowledge about how the product works.

Remember that I said Test Engineer, and not Quality Assurance Engineer in the title of this blog.  A QAE could rightfully say that he only does black box testing and should see the system as a customer would see the system.  Test Engineers on the other hand should do some white box testing, and should be familiar of the inner workings of the system being tested.  Why is this beneficial?

If you don't know how it's supposed to work, how are you supposed to know when you have a correct answer or not?  I have often given an analogy that Test Engineers are teachers, and Developers are students.  Test Engineers must grade what the Developers do.  If the Test Engineer himself doesn't know what the answer is, that is akin to a teacher asking the student what the answer should be before the student takes the test.  Letting developers have this level of control over the validity of a product is no different than letting the fox guard the hen house ("oh, that's 'working as designed', we MEANT for it to behave that way").

The second big reason you want Test Engineers to be developers and know how the system works is for first level triage.  If your Test Engineers have no clue how the underlying system works, how can you expect them to debug it?  Is the problem in the driver?  The firmware?  Maybe it's somewhere higher up in the stack, and it is a framework or application they are using.  Or what if it's a low-level physical problem (jitter, noise, etc)?  If all your Test Engineers do is execute tests from a Test Plan, without understanding to at least some level, the interactions of the various components, he will be ineffective at providing first level debugging, and this burden will fall to a developer.  The danger here is that an ineffective defect assignment will waste a developer's time (for example, if the Test Engineer assumed the defect was firmware problem, but it turned out to be a driver problem).


And finally, how is a Test Engineer supposed to come up with new Test Cases or ad-hoc tests if he doesn't understand the system from a low-level perspective.  At best, he can read a spec and determine what should be tested, but he won't necessarily know how to stress a feature, nor will he necessarily understand how to come up with invalid inputs (negative testing).  Being able to "see" the weak points in a product requires knowing how that system works.  Many famous martial arts masters of the past were also great healers of their time, because by understanding how the body worked, they were much better at knowing the weaknesses of the body.  The same logic applies to testing.

To give you a real world example, suppose you want to use sg_utils to send generic SCSI commands.  This is all well and good, but suppose something doesn't go right.  Where was the problem?  If you don't know what a CDB (command descriptor block) is, or how to read a SAS trace, what good will it do you?  At best, you have thrown the problem over the wall to a developer to fix.  This is ok for a QAE, but not a Test Engineer.

And as I mentioned in my previous blog, part of the reason Test Engineers get little respect is because they are seen by developers as little more than testers.  Although Test Driven Development has gained some traction, notice that it focuses on developers writing better unit tests.  The concept of Development Driven Testing has unfortunately not caught on.

Monday, May 16, 2011

Test Engineers don't get any respect

Had I known the stigma of belonging to the Test group of a company, I probably never would have become a Test Engineer.  Now technically, what I do isn't what most Test Engineers do, and although that is my official title, I am closer to what would be called a Software Development Engineer in Test.


What amazes me is the attitude people have in regards to the skill set of Test Engineers.  While I am not a guru in any of these languages, I have written production code in C, C++, Java, C#, Perl, Python, SQL,  and Labview.  I have used (but again, am no master in) a broad array of technologies including SOAP (using Apache CXF), xmlrpc (using Apache ws-xmlrpc), Swing, SWT, some small Eclipse plugins, just to name a few.  So although my knowledge isn't necessarily deep, it is broad. 


When I first got to my new job, I was talking with one of the developers.  I mentioned that at my previous job, I was a developer.  He looked at me quizzically and said, "so you demoted yourself to a Test Engineer?".  I had a puzzled look as well, because I had never been a Test Engineer, nor had I worked for a Test department before. Over time however, I grew to understand why such denigrating attitudes exist, and I will explore them in later blogs.

Nevertheless, I essentially had to prove that I could indeed program and even design relatively large scale projects by myself.  Developers seem aghast when during code reviews I point out things that seem to surprise them.  For example, code paths that they forgot to free a malloc'ed pointer to, or why you shouldn't write 1000 line functions (and god-forbid that they cut-and-paste a function from somewhere else).  They also seem aghast when I counter their feeble argument that breaking down too many functions into sub-functions would cause overhead by telling them to A) profile it and B) inline their functions.

Still, there is some truth to the notion that many Test Engineers are not all that technically savvy, and so I don't blame developers for thinking that at least some Test Engineers are technically deficient.  And this realization has made me determined to NOT be a Test Engineer again.


Just to relate one last story, I knew another Test Engineer who had to call someone at a company in order to purchase a product of theirs that would be utilized by their test framework.  After some discussion, the sales rep basically asked to speak to the developers in charge, or someone who knew what this framework really did.  The great irony was that the test framework was designed and programmed by the very Test Engineer the sales rep was talking to.


Test Engineers....we get no respect.

Thursday, April 21, 2011

Unfortunately, I haven't had a chance to start porting any of the OpenGL SuperBible classes to either Java or Clojure yet.  Hopefully now that I've got a long weekend, I can focus some on it.  Also, my priorities have shifted a little somewhat.

At my work, I've been tinkering with the possibility of using JBoss's netty project to implement some of the things we need to do.  As it so happens, my little game project will also need some networking capability.  For example, it must have the ability to let connected users chat in a room, and also to update "figures" on a map.  I also think it would be useful for getting updates on the software itself.

Netty, though a well documented project, also has a bit of a learning curve.  One of the things I'd like to be able to do is to launch a subprocess in Java, capture that process's stdout, and redirect it to a Netty channel.  Hopefully, I can do this in clojure.  This of course also means I need to build my own version of clojure.contrib.shell-out, since that doesn't seem to do exactly what I need (though I probably should take a look at the source).

In other words, there's a lot of stuff I need to do:


  1. Reimplement my own version of clojure.contrib.shell-out
  2. Create a netty based async IO system I can use for:
    • Chatting between players/GM
    • Launch subprocess and redirect stdout to the netty channel
    • Update figures on a map
    • Download updates to the project
  3. Create a subprocess launcher that I have access to the stdout
  4. Start wrapping the SuperBible libraries (probably straight to clojure via lwjgl)

I've actually begun updating the sojourner project again, though none of the bullet points listed above are anywhere close to done.  I also want to lay down a little general project planning for sojourner rather than just tackle things on the fly like I have been doing.  Having a roadmap helps enforce goals and you can see where you are heading and how much farther you have to go.


Saturday, April 9, 2011

Start porting some of OpenGL SuperBible classes to clojure

My hard copy book of The Joy of Clojure finally came in, and I feel reinvigorated to start programming in my spare time.  As I've been reading the SuperBible book, I realize that it is very much geared towards using its built in classes.  For example, it uses a GLShaderManager class to handle a lot of the shader programs, and it has its own library that deals with a lot of the math basics.

Since I want to do this in clojure, I'm going to have to port or at least heavily borrow from these C++ classes in order to use them.  It's also been about 2 months since I've touched any clojure code, and it's already gotten quite rusty.  For example, while reading through the Joy of Clojure book, I already forgot the differences between map, apply and reduce.  So I hopefully porting the C++ classes to clojure will be a good way to refreshen my clojure.

I'm still not sure what the best way to do this will be.  On one hand, it might be better to port it to Java first, and then make clojure wrappers around it.  If I do that, more people will be able to benefit from it, and I could also in theory use jython or Scala with it if I wanted (not that I know Scala that well).  On the other hand, I think that will not only be more work, there might be stuff lost in translation.  Just like how the Bible got corrupted by going from Aramaic to Latin to English, so too I think would going from C++ to Java to clojure.  That being said, I'll have to deal with Java at some level since I will be using lwjgl as my interface to OpenGL.

So starting today, I'll start work on this port in my sojourner project.  Which by the way, I've totally forgotten how to use leiningen with.  I started looking at cake, but its Windows support seems to be a little iffy, even though I dislike Windows.  Speaking of which, I might also throw Chakra on my main desktop, as its a more user-friendly version of Arch linux.  My other option is throwing Sabayon.  I really want to use a rolling-release style of linux rather than point release versions since upgrading almost inevitably winds up breaking something pretty badly.

Wednesday, March 23, 2011

OpenGL one step at a time

After realizing that Oracle was going to move to JavaFX, and that JavaFX could do hardware acceleration, I decided I may as well learn 3d programming.  Since I'm a believer in cross-platformness, I am going to use OpenGL for my programming.

From my initial foray into learning OpenGL, it appears that starting with version 3.0 of OpenGL, the use of GLSL is kind of mandatory (at least if you use the core profile, I am a bit confused about the compatibility spec).  But basically, the old fixed function pipeline is being deprecated and should eventually go the way of the dodo.

So I finally got my OpenGL SuperBible 5th edition book on Friday.  I think I will create a new project under bitbucket which will basically be me following the book's examples, but using Clojure.  How will I manage that since the code examples are all C/C++?  Fortunately, lwjgl (Lightweight Java Game Library) has ported almost all of the OpenGL Core and GLSL API to java.

This will require a bit of mental juggling.  I will have to convert C/C++ to Java, and then from Java to Clojure.  This will also be interesting because OpenGL is in some ways a huge state machine, and Clojure being a functional language, takes a different spin on saving state.  That being said, I don't think there's a Java port for GLSL.  And GLSL is required for shaders.

GLSL is basically a weird version of C with very specific data types and keywords.  For example, GLSL makes a distinction between uniform data flow and varying data flow.  If you have some nested if/else blocks, or switches, then that would be varying data flow, and variables must be noted as such.  Also, GLSL has many specific built-in data types representing vectors and matrices.

What really surprised me is that shader programs are stored as strings and then fed to a compilation unit on the video card.  Basically it's compiling them on the fly.  I did see however that it appears that in OpenGL 4.1, you can store and open binary files (presumably pre-compiled shaders?).  I'll have to study the stock shaders that the book's project comes with.  Although GLSL kind of looks like C code, there are many new keywords that I don't fully understand yet.  For example, invariant, uniform, or varying.

The OpenGL SuperBible weighs in at almost 1000 pages, although a good 300+ pages are Man Pages from OpenGL.  Nevertheless, that leaves around 650 pages just on OpenGL.  It appears that it's mostly about OpenGL itself and not GLSL, though there does appear to be one chapter devoted to it.  Combined with the fact that I am also going to have to refresh my knowledge of linear algebra, this is going to be extremely slow going.

Also, the book is geared towards writing C++ programs, using GLUT or freeglut, and glew.  Furthermore, the book's project comes with a home-grown library called GLTools which has a lot of utility type functions.  In essence, I am going to have to translate all this into Java-speak, and more specifically into lwjgl speak.  For example, lwjgl comes with its own windowing classes that has the same job role as GLUT.  I haven't gotten far enough into the book, but I also wonder if it goes into any controller input issues (for example, getting input from a joystick).

I also want to get in on OpenCL, the open version of Nvidia's CUDA which allows for processing on a GPU's stream units.  The lwjgl project also has ported (most of) OpenCL which means I can use this as well.  Given the vast parallelism given by the GPU, this should be able to make for some interesting AI possibilities.  What will be really interesting as I play with this will be to see the differences between writing concurrent programs for CPU's (which generally speaking are Task oriented in OpenCL lingo), and concurrent programs for GPUs (which are generally Data oriented).

I'm really curious how I can deal with OpenGL's state machine using clojure.  But I don't know enough about the state machine to understand how to best model a clojure representation of it.

Anyhow, this is all pretty interesting, and hopefully within the next week or two, I'll be updating my sorely ignored sojourner project with some new stuff.

Sunday, February 20, 2011

Slow going

I haven't posted too much here recently for a few reasons.

1.  I'm boning up on OpenGL, particularly GLSL
2.  I'm re-learning linear algebra (in order to do matrix multiplication)
3.  I'm getting back to basics with clojure and reading the rest of The Joy of Clojure and Clojure in Action
4.  I'm getting serious about working out again

I will post soon a blog about debugging shared libraries however.

So I haven't had time to work on the sojourner project directly.  I really wish I had a job where I could program in clojure (or lisp) full time.  I also need to get more serious about math again.  I hated how all my math skills rusted away from non-use.

I did have a strange revelation though about math while re-reading Steve Hagan's excellent "Buddhism is not What You Think".  One of the central tenets of Buddhism is impermanence.  Nothing is permanent and everything changes from moment to moment.  This is in direct contrast to functional programming and mathematics in general.  Or at least so I at first thought.

A number is unchanging.  5 has been, is and always shall be 5.  But what exactly is 5?  Is it an abstraction?  A concept?  Buddhism makes it clear that reality is not a concept.  Even mathematicians debate about the "reality" of much of math.  To put it another way, is there truly a pure right angle that exists in nature?  When you say that you have 3 quarters, is 3 a thing, or simply a pointer to reality?

Deep down, I wish I had been a philosopher.  And one day, I will put all this aside and become a mystic.  But for now, I am still beholden to the world.  I do think i have entered the stream, but I am still reluctant to cross to the other side.