Tuesday, January 4, 2011

Coded UI testing for Silverlight application


So I have started by looking at:


I have manually created my testing project (wanted a different name)

Tried the application and received this error:



So it seems the video forgot a step…

So I added a reference to the dll to my Silverlight project :

C:\Program Files (x86)\Common Files\microsoft shared\VSTT\10.0\UITestExtensionPackages\SilverlightUIAutomationHelper\Microsoft.VisualStudio.TestTools.UITest.Extension.SilverlightUIAutomationHelper.dll


C:\Program Files\Common Files\microsoft shared\VSTT\10.0\UITestExtensionPackages\SilverlightUIAutomationHelper\Microsoft.VisualStudio.TestTools.UITest.Extension.SilverlightUIAutomationHelper.dll


Found this tip: http://blogs.microsoft.co.il/blogs/shair/archive/2010/07/22/coded-ui-test-tip-3-locate-controls-using-win-i.aspx

About using Window+I to locate controls – didn't work for me…


For coded UI I need to add ids to each element that I want to test but in Silverlight best practices it says not to!


Silverlight Best Practices:


//TODO: add a link to the best practices

//TODO: too raw…

ArcGIS Server layer problem (DB is down)


So I got a task from my team leader to fix something in our implementation of FeatureLayer (in the Silverlight map).

I started last week and this morning I opened the map and saw white – No layers and the background layer took a few minutes to load.

So I fired up the ArcGIS Server Management site at: http://SERVER_NAME/ArcGIS/Manager/Default.aspx

Opened the log:


And saw this:


(Just imagine 8 more rows of the same text)

WARNING |  The Layer:'SchemaName.LayerName' in Map:'Layers' is invalid. Failure to access the DBMS server

So the first thing I tried was googling it and couldn't find any relevant data.

So since the error was DBMS I tried opening the SQL Server Management and got this:


When the server returned the application (of course) didn't start working…

I looked at ArcGIS server:


WARNING | The context has been automatically released because the Context Usage Timeout Interval has elapsed.

ERROR | Server Context creation failed on machine SERVER_NAME.

And then this:


ERROR | Container process 3592 has crashed on machine SERVER_NAME.

The problem was solved by deleting the cache (see Clearing ArcGIS Server REST API Cache) and restarting the ArcGis Service (see Restart ArcGIS Server service).

It seems ArcGIS Server saves in it's cache the error and doesn't let go until you manually refresh the cache – fun isn't it?


Restart ArcGIS Server service


All you have to do is go to the ArcGIS Server manager site at:


In Services select the Manage Services:


Select the service you want to restart:


Click on restart:


Now just wait for it to finish:


When the process is done be sure to check the status of the service:


Started is good, Stopped is bad:



//TODO: Write a basic post on ArcGIS Server


Simplify and the ArcEngine license


So I have tried to make my code simplify the IPolyline result I had by:

        public static IPolyline CreatePolyline(params MapPoint[] points)


            IPolyline polyline = new PolylineClass() { SpatialReference = CreateWgsSpatialReference() };


            foreach (var point in points)






            return polyline;




The Unit Test that test this part of code won't pass, a pop up pops up:



Initialization Error


The runtime application type must be specified before license initialization.





And the different frameworks for unit tests show the same kind of error:

Resharper shows that test as Aborted:


VSTS shows that test as Error:



I think this means that Simplify won't work with ArcEngine license but tell me what you think.


Rename Polyline layer


Why does it work?

You know that question?

For a long long time I had one test in DeploymentWorkspaceUtils that just didn't want to pass, it was called:



The test was simple:

1.       Create a layer of type polyline

2.       Put a feature in the layer

3.       Rename the layer

4.       Get the data back from the renamed layer

I had two more tests identical to this test but with point and polygon data.

But in the part of renaming the layer I got the following error:

System.Runtime.InteropServices.COMException: The number of points is less than required for feature


Today I had some time and got back to this test, I thought to myself that since the error is of the number of points I figured the trouble was with reading the data.

My second thought was that I didn't clone the geometry returned into my entity, I placed a breakpoint in my entity and waited and waited some more…

Then I tried to slam my head to the wall – I didn't use entity in rename since I didn't have any entity.

I looked again and in the rename I simply used a List<IFeature>, than I thought about the most annoying Boolean in IWorkspace – IsRecycling mine was of course set to true.

Now the real question is why didn't the Polygon fail as well???


Then I thought to myself maybe the geometry in the DB for the polyline is not simplified lets try to simplify it! The result was the same old error => The number of points is less than required for feature


So I changed my test to be with two features in step 2 and added an assert that the geometry length (for IPolygon and IPolyline) is greater than zero. For the point I added an  assert on the X and Y of the point.

And still the point and the polygon tests pass, the polygon's length was ~40 which is to say greater than zero, WHY???


I decided to add a test that verifies that the 2 entities are different and now the point and polygon tests fail and the polyline test (still) throws an exception.



In the end I decided to just fix the damn test and try not to think logically with ESRI…



Stuck Database – the JOY!

I was playing with extending Fluent Migrator and wanted to check what was left in my DB after the last try.

Trying to open the tables sub folder gave me this error:


So I tried taking the DB offline and got stuck with:


Closing that window and trying to open the DB again got me:


So I have decided to go brutal, I opened Computer Management->Services and Applications->Services and stopped the SQL Server (MSSQLSERVER) service:


And then started it again (I like to give it a few second to relax then doing the restart).

Now reconnecting to the DB works.


But what about the bug that caused all of this?

I tried the test again, but this time tried to open the Tables folder at the same time:


The test is stuck on:



What I found out?

The test is stuck when trying to open a workspace to the SDE. But (this time) I don't blame ESRI because it seems the current connection to SQL doesn't allow any other connection – I can't even open SQL Server Management.

What I found in the code?

Fluent Migrator opens a connection and then begins a transaction – and closes it only when all the "StepUp"s are complete. While I want to open a SDE connection in the middle of that transaction – and get stuck doing it.


Deleting SDE left over tables


Warning: Do this only if you don't have any other choice!

So I got to a stage in my code where SQL Server Management shown:


And my test showed the following error:

ERROR: Table already registered [Microsoft SQL Server Native Client 10.0: Violation of UNIQUE KEY constraint 'registry_uk2'. Cannot insert duplicate key in object 'sde.SDE_table_registry'. The duplicate key value is (CARS, GIS, FLUENTMIGRATOR).] [FluentMigrator.GIS.CARS]

What does it mean?

It means I deleted a table with "DROP TABLE" where I needed to use ArcObjects/ArcCatalog and all I got from it is this lousy T shirt… Just without the T shirt…

So it should come as no surprise that SDE stores the metadata of their feature/table layers, and when deleting tables they get deleted from it.

The SDE Database table structure:


(At least on my computer)

From the Exception table - SDE_table_registry contains:


See line 7 – that’s our CARS non layer table

Lets delete those rows.

But don't think we are done, there is still the column registry table - SDE_column_registry:


Lets delete those rows as well.


For feature Layers the situation is a bit more complex:

For example we look at REGIONS table:

At SDE_table_registry:


At SDE_column_registry:


At SDE_layers:


At SDE_geometry_columns:


(Don't worry we are not yet done!)




                      sde.GDB_ITEMS ON sde.GDB_ITEMRELATIONSHIPS.DestID = sde.GDB_ITEMS.UUID

we get some items from GDB_ITEMS (see next item).




And we must not forget the SPs – in our database we need to delete the SPs whose number is not used by any table (see SDE – A look at the layer table structure).


And at least according to the profiler when delete another feature layer be sure to look at SDE_metadata.


To Sum it all together – SDE sucks!

But now here is a script I wrote (I am not a DBA so there might be mistakes) that does all this deletes (be sure to replace all the grey matter):

declare @LayerId int

declare @SdeLockId int

declare @DatabaseName varchar(32)

declare @TableName varchar(128)

declare @OwnerName varchar(32)


set @DatabaseName = 'FLUENTMIGRATOR'

set @TableName = 'REGIONS'

set @OwnerName = 'GIS'



--Getting the layer id

Select @LayerId=layer_id

from sde.sde.SDE_layers

where database_name=@DatabaseName and table_name=@TableName and owner=@OwnerName

--Getting the lock id

Select @SdeLockId= sde_id

from sde.sde.SDE_layer_locks

where layer_id=@LayerId






DELETE FROM sde.SDE_column_registry WHERE owner=@OwnerName and table_name=@TableName and database_name=@DatabaseName

DELETE FROM sde.SDE_geometry_columns WHERE f_table_catalog=@DatabaseName and f_table_schema=@OwnerName and f_table_name = @TableName

DELETE FROM sde.SDE_layers WHERE database_name=@DatabaseName and owner=@OwnerName and table_name = @TableName

DELETE FROM sde.SDE_table_registry WHERE database_name=@DatabaseName and owner=@OwnerName and table_name = @TableName


exec sde.sde.SDE_layer_def_delete @LayerId

exec sde.sde.SDE_geocol_def_delete @DatabaseName,@OwnerName,@TableName,N'SHAPE'


exec sde.sde.SDE_layer_lock_def_delete @SdeLockId,@LayerId,'N'

exec sde.sde.SDE_layer_lock_def_delete_user @SdeLockId

exec sde.sde.SDE_state_lock_def_delete_user @SdeLockId

exec sde.sde.SDE_table_lock_def_delete_user @SdeLockId

exec sde.sde.SDE_object_lock_def_delete_user @SdeLockId

exec sde.sde.SDE_pinfo_def_delete @SdeLockId


This seems to work for both regular tables and feature layers.

If someone has a better suggestions for this script please let me know.



del.icio.us Tags: ,,,,,
IceRocket Tags: ,,,,,