Tuesday, January 4, 2011

Coded UI testing for Silverlight application

 

So I have started by looking at:

http://timheuer.com/blog/archive/2010/11/24/coded-ui-available-for-silverlight-4.aspx

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

Tried the application and received this error:

image

 

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:

http://www.kunal-chowdhury.com/2010/08/some-best-practices-for-silverlight.html

//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:

image

And saw this:

image

(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:

image

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

I looked at ArcGIS server:

image

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:

image

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:

http://SERVER_NAME/ArcGIS/Manager/Default.aspx

In Services select the Manage Services:

image

Select the service you want to restart:

image

Click on restart:

image

Now just wait for it to finish:

image

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

image

Started is good, Stopped is bad:

image

 

//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)

            {

                polyline.AddPoint(CreatePoint(point));

            }

            ((ITopologicalOperator)polyline).Simplify();

 

            return polyline;

        }

 

 

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

image

---------------------------

Initialization Error

---------------------------

The runtime application type must be specified before license initialization.

---------------------------

OK  

---------------------------

 

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

Resharper shows that test as Aborted:

image

VSTS shows that test as Error:

image

image

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:

Deployment_RenameLayer_GeometryPolylineOldLayerHasData_GetData

 

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:

image

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

image

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

image

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:

image

The test is stuck on:

image

 

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:

image

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:

image

(At least on my computer)

From the Exception table - SDE_table_registry contains:

image

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:

image

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:

image

At SDE_column_registry:

image

At SDE_layers:

image

At SDE_geometry_columns:

image

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

At GDB_ITEMRELATIONSHIPS if we query:

SELECT     sde.GDB_ITEMS.*, sde.GDB_ITEMRELATIONSHIPS.*

FROM         sde.GDB_ITEMRELATIONSHIPS INNER JOIN

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

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

At GDB_ITEMS:

image

And

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.GDB_ITEMRELATIONSHIPS

WHERE DestID in (SELECT UUID FROM sde.GDB_ITEMS WHERE Name = 'FluentMigrator.GIS.REGIONS')

DELETE FROM sde.GDB_ITEMS WHERE Name = 'FluentMigrator.GIS.REGIONS'

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: ,,,,,