Wednesday, June 09, 2010

fitSharp with .NET 4.0 hangs Fitnesse test

I ran into an issue with fitSharp with .NET 4.0.  I built a very simple test page, with a ColumnFixture test.  Clicked the test button, and Fitnesse hung.

I made several edits to the test page, and still had no luck.  Just hanging, with no indication what was causing the problem.  So, I went to commandline and manually executed the fitSharp runner (Runner.exe) with the command line that was being generated from the test page.  Here are the results that I got:

System.IO.FileLoadException: Could not load file or assembly 'file:///C:\tools\fitSharp\fit.dll' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)
File name: 'file:///C:\tools\fitSharp\fit.dll' ---> System.NotSupportedException: An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework.This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information.
   at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark&stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm,Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
   at System.Reflection.Assembly.LoadFrom(String assemblyFile)
   at fitSharp.Machine.Engine.ApplicationUnderTest.AddAssembly(String assemblyName)
   at fitSharp.Machine.Application.Shell.ParseArguments(String[] commandLineArguments)
   at fitSharp.Machine.Application.Shell.RunInCurrentDomain(String[] commandLineArguments)
   at fitSharp.Machine.Application.Shell.Run(String[] commandLineArguments)

.NET 4.0 has made some changes to the default CAS policies (some details here.

The resolution to the problem?  Simply creating a configuration file for Runner.exe to enable the loadFromRemoteSources option for the assembly.

Create a file called Runner.exe.config in the fitSharp folder (with Runner.exe), and add the following to the file:

<configuration>
  <runtime>
    <loadFromRemoteSources enabled="true" />
  </runtime>
</configuration>

Re-run the test in Fitnesse, and all should be good!

Friday, May 01, 2009

Marshaling tips

I was trying to solve an interesting problem in C# where I was marshaling a structure from the OpenSSL library.  The X509 structure has lots of parameters, but one called "references" is what I was interested in for this challenge.  I have managed objects that wrap the native pointer from OpenSSL, but needed to manage the lifetime of the native pointers when managed objects were finalized and whether they should destroy or release a reference to the native pointer.

I tried a few methods, and decided that the best way to solve the problem would be to utilize the reference counting implemented in OpenSSL.  The tricky part is...  Most OpenSSL structures have a "references" integer that is incremented/decremented by the CRYPTO_add() method which takes a pointer to the "references" integer from the structure.  So, my challenge was to find a way to get a pointer to the "references" integer in the native OpenSSL structure, and pass it from managed code to the CRYPTO_add() method via p/invoke.

Here's how I made it work.

First, provide the structure definition in managed code for the X509 strucuture:

        [StructLayout(LayoutKind.Sequential)]
        private struct X509
        {
            public IntPtr cert_info;
            public IntPtr sig_alg;
            public IntPtr signature;
            public int valid;
            public int references;
            public IntPtr name;
            #region CRYPTO_EX_DATA ex_data
            public IntPtr ex_data_sk;
            public int ex_data_dummy;
            #endregion
            public int ex_pathlen;
            public uint ex_flags;
            public uint ex_kusage;
            public uint ex_xkusage;
            public uint ex_nscert;
            public IntPtr skid;
            public IntPtr akid;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = Native.SHA_DIGEST_LENGTH)]
            public byte[] sha1_hash;
            public IntPtr aux;
        }

Next, implement an Addref method that gets the offset of the "references" member, and then create an IntPtr to that location to pass into the CRYPTO_add() method.

        public override void Addref()
        {
            int offset = (int)Marshal.OffsetOf(typeof(X509), "references");
            IntPtr offset_ptr = new IntPtr((int)ptr + offset);
            Native.CRYPTO_add_lock(offset_ptr, 1, Native.CryptoLockTypes.CRYPTO_LOCK_X509, "X509Certificate.cs", 0);
        }

The Marshal.OffsetOf() method returns an IntPtr that can safely be cast to an integer.  This provides the offset to the member in the native structure.

The offset_ptr is a new IntPtr object that takes the native X509 pointer and adds the offset to the references member.  Once the value is added, the resulting IntPtr object contains a pointer to the "references" member in the native structure, and can be passed into the CRYPTO_add() method.

Hope this helps someone!

Blogged with the Flock Browser

Labels: , , , , , , , , ,

Tuesday, August 19, 2008

Making sense of organizational change

Excessive or frivolous reorganizations are disruptive and counterproductive. Many technology executives are surprisingly inept when it comes to effective reorganizations.

View Original Article

Blogged with the Flock Browser

Labels: , ,

Sunday, August 17, 2008

Learning PHP

I spent some time this weekend to start learning PHP.  I browsed the web for good starter links for creating dynamic web pages with MySQL.  Obviously, the starting point was downloading and installing Apache, PHP5, and MySQL.  The installation went smoothly, I chose the Windows binary zip packages for PHP, and ran the MSI installs for Apache and MySQL.  After configuring Apache for PHP, and making minor modifications to the PHP.ini file, I ran my first PHP page (<?php phpinfo(); ?>).  This gave me a nicely formatted page that showed the PHP installation options and verified that everything was working.

Figuring that learning a new language from scratch may present some challenges, I started searching for a PHP editor that might ease the learning curve a little.  After searching for a while, I decided on Eclipse with the PDT.  I downloaded Eclipse, and then the Java 1.5 JRE, and then extracted the PDT binaries into the Eclipse folder structure and fired it up.

Eclipse is a very nice IDE that supports lots of interesting extensions.  The PDT module added on nicely and provided the option to create a PHP project, configure debuging with xdebug, and provided a very helpful panel (in the PHP perspective) called "PHP Functions" that allowed me to search for classes and functions available in PHP.

After overcoming the installation and configuration hurdle, I was ready to create my first *real* PHP application.  But, what would be a good application to start with?  I decided to create a simple contact management web application that would contain name, photo, e-mail, and phone number.  This application should introduce me to MySQL add/update/delete, dynamic tables/forms, postbacks, redirection, session/post/get variables,  file upload, sending image data from the server, and more.

I laid out the application in 3 pages:

Main Page
The main page will show the list of all contacts, it will display all contacts in the database, and access an images table via an imageid field in the contact row.
Add/Edit page
The add/edit page will allow creation and editing of the name, e-mail, phone, and also allow a photo to be uploaded for the contact.
Image retrieval page
The image retrieval page will read an imageid from the query string on the url and lookup the image data in the database, and send the image data back as an http response.

I created the tables in the database, and started coding away!  Some of the issues that I had to learn/overcome:
  • String concatenation (. instead of +)
  • Handling/determining postbacks (looking for hidden field or valid $_POST array values)
  • How to redirect the browser (setting the HTTP header before any other output)
  • Global variables (defining and using)
  • Configuring the xdebug debugger in Eclipse (minor config file tweaks)
  • Handling file uploads (PHP provides a lot of help with this!)
  • Handling images (PHP provides a lot of help with this!)
  • Accessing a MySQL database (intuitive implementation)
  • MySQL BLOB size limitations

After about 4-5 total hours...  I had a working application that allowed the addition/editing of contacts information, photo uploads in main, add, and edit pages, and display of photos in main page and edit page.  Knowing ASP/ASP.NET helped with some of the concepts, but overall PHP provides A LOT of functionality that helps out with common and advanced web application development.  I know that I have just scratched the surface with this application, but I have learned enough to know that I will continue developing with PHP!

I have already started researching the WS02 Web Services Framework for PHP.  They have a complete WS-* implementation for PHP that looks very interesting!



Blogged with the Flock Browser

Sunday, July 13, 2008

Google Lively... First impressions

I installed the Google Lively 3D chat application today.  So, I figured I'd write a few comments about my first impressions.

Launching the application the first time is a little confusing, you need to use your Google ID to sign in, then select a Lively ID - I tried to use my Google ID again, but it was already in use.  (Was it saying that my account was already in use?  Or someone else using the ID in Lively at that point in time?  I figured it should be the first problem -- as I have never had an issue my ID being unique before...  So, I selected a new ID, and starting logging into a chat room.

I tried the Google room first.  The UI came up and starting initializing the room.  This took a long time, and a LOT of memory.  There was a note on the bottom of the screen that said something about the room being at full capacity, but it let me in...  So, I waited.  The longer it took, the more curious I became...  So, I opened up Task Manager and was surprised to see the lively.exe utilizing 700+MB of virtual memory, and 140MB of physical memory!  I am currently working on an old laptop that only has 1GB of memory...  So, that explains the loading performance! :(

I thought that the high memory load might be related to the full room, so, I exited out and signed into the High School room.  There were only a handful of people in this room, but the application still needed the 700MB of memory!

I was able to play around a little while in this room.  The lag wasn't too bad, so I tested out some of the avatar sounds, and object interactivity.  It's pretty cool.

Overall, a really neat idea from Google.  I'm sure it'll grow over time and allow more avatar customizations, rooms, etc.  But, for now...  It's a lot of overhead for a "chat" client.  (I'll probably get burned for this...  So, I'll state that I do realize that it's meant to be more than just a chat client!).  So, I won't give up just yet...  But, I will give up trying to access it from my laptop! ;)

Saturday, July 12, 2008

A Saturday spent running Cat 5

We have been doing remodeling on the house since we moved in (a year ago).  Installing hardwoods on the entire first floor, remodeling the kitchen, moving walls, finishing drywall, etc.  It's a lot of work for a do-it yourselfer that works 50-60 hours a week at his day job, but I'm getting close to done!

Today was the day to solve the "I'm tired of tripping over the damn network cables when I walk into the office!" day.  I have never created my own network cables, but have had some experience with running cables through the walls.  So, I headed to Home Depot and picked up some Cat 5 cabling, RJ45 jacks, and wall plates.

I spent some time in the basement (thank god for the basement, it made the job much easier being able to run the cables through the open ceiling).  I decided on the location of the wall plates, cut holes in the drywall for each plate and went to the basement to drill some holes.  After guestimating on the location of the wall plate hole above me, I drilled the holes and fished the wire through them.  Back upstairs to find the wires in the wall.  I had to do this a couple of times. :(  But, finally succeeded!  I read the instructions for the wiring diagram for the RJ45 plates and connectors (a few times), set the wires, crimped and it worked!

I screwed the wall plates into the walls, cleaned up the mess, and marked another item off the really long "honey-do" list!

Not a bad Saturday...  Now it's time to grill some chicken and sip some well deserved Crown Royal!  Tomorrow, I'll be back in the basement organizing, and setting up the weight room.

Friday, July 11, 2008

iPhone v2.0 Upgrade Hell!

Apple has finally released v2.0 of the iPhone firmware and the 3G iPhone.  Great news!  At least that's what I thought.  I have owned an iPhone for about a year now...  I have updated the firmware to pick up the new/interesting additions and bug fixes with no issues.  So, I would naturally assume that upgrading to v2.0 would be just as easy.  Well, I guess that's where the saying: assume=ass u me comes from...

The release of v2.0 upgrades for existing iPhone users and the new 3G iPhone at the same time has overloaded the activation server.  I can understand how this happens (technically), but Apple should have anticipated the load and built up the infrastructure prior to the release of the products!  This isn't their first rodeo, they forcasted (and counted) on the demand... So, why didn't they spend a little money to further build out the activation infrastructure to handle the additional activation load?  They obviously handled it from the site that serves the upgrades... Nobody seems to have any problems downloading and installing the upgrade, they just can't re/activate afterwards.

The major issue for previous iPhone users is...  the asinine model that requires the iPhone to be re-activated after every firmware upgrade.  Without activation, the phone is useless...  So, there are lots of people that are extremely upset with Apple at this point because their phones have been bricked until the activation server is upgraded to handle the load (or they get lucky after clicking back and forth between the iPhone button in iTunes).

Another major problem with Apple is...  There is no information about activation delays on their web site!  iTunes prompts you with cryptic errors messages that don't even warrant a search hit on the Apple support site.  What is up with that?  After reading other blogs, I am seeing that some people are waiting on the phone for technical support, and after an hour or so... they get to talk to someone or the call is just disconnected.  Not good.

Apple has made a huge mistake with this release...  They should have invested in the activation server infrastructure to handle the load (the estimated load * 2), and if there are problems...  Post something on your web site!  People are going there first, so at least man up and give the users (that you have screwed) some information on what's going on, and when we can expect the problem to be resolved!

Also, you need to re-think the re-activation requirement for existing iPhone customers.  The last thing you should do is de-activate something that is currently working for an end user.  This is a very quick way to lose customers.  The iPhone is a great product, but it's not the only one on the block.  There are a lot of touch competitors coming into the space, and they will be more than happy to take the disgruntled Apple customers!

So, in closing...  Apple --  WAKE UP!  And take care of your customers!