Sunday, November 25, 2012

Two Ways of Initializing a New Object in C#

Recently I posted a question about the different ways one can initialize an object in a C# class. I generally use EXAMPLE 1 below. Resharper suggests I use EXAMPLE 2. EXAMPLE 1 is more intuitive to me (since it is want I always use). However my friend FC pointed out he prefers to "choose a syntax that directly associates the data with the name of its field, rather than relying on the order of the arguments, wherein various perils are wrought", meaning Example 2. I find this argument quite compelling.
My amigo BS has a very nice explanation "The first is required if you need those values for processing during the initialization of your object." This is corroborated in the linked MSDN article at the bottom. BS goes on to say: EXAMPLE 1 "can also be used as a way to force anyone creating the object to always provide those values. The second is useful for things like Data Contract objects where you need a parameter-less constructor for serialization and to assign values directly to its properties in one step. The key difference is values are assigned after construction in the second example."

Even
though my tests tend not to have the serialization requirements facilitated by EXAMPLE 2 I will consider switching course for the sole value stated by FC.
EXAMPLE 1
public static void Main()
{
     StudentName student1 = new StudentName("Marcus", "Deatonus");
...
}
EXAMPLE 2
public static void Main()
{
     StudentName student1 = new StudentName
       {
          FirstName = "Chris",
          LastName = "Bellcamp"
       };
...
}
REFERENCES
http://msdn.microsoft.com/en-us/library/vstudio/bb397680.aspx

Monday, November 12, 2012

SQL Server Unicode and Codepage Support




STEP 1: Find all your collations...



CREATE TABLE #CollationTbl
(ID INT Identity (1,1),ServerCollation sql_variant, DatabaseName varchar(300),    DatabaseCollation sql_variant ,    DatabaseCollationDescription nVarchar(500))

EXEC sp_MSforeachdb


'

Declare
    @1 sql_variant = (SELECT SERVERPROPERTY(''Collation''))
    ,@2 varchar(300) = "?"
    ,@3 sql_variant = (SELECT DATABASEPROPERTYEX("?",''Collation''))
    ,@4 varchar(300)
   
    SET @4 = (SELECT DESCRIPTION FROM fn_helpcollations() WHERE Name = @3)



INSERT INTO #CollationTbl
SELECT @1 , @2, @3, @4
    ;
   
'

SELECT * FROM #CollationTbl;

DROP TABLE #CollationTbl;

STEP 2: Look at each element of the collation. The code page element should be the same or lower page than the code page set in the OS.

The OS codepage can be found using

C:>systeminfo|findstr -i locale
System Locale:             en-us;English (United States)
Input Locale:              N/A

You can also try using chcp, but it really defines the codepage used in the command prompt session, not the codepage for the server. This is useful for debugging character/codepage incompatibility.

C>chcp
Active code page: 437

References
http://msdn.microsoft.com/en-us/library/ms143726%28v=sql.105%29.aspx
http://stackoverflow.com/questions/1259084/what-encoding-code-page-is-cmd-exe-using
http://msdn.microsoft.com/en-us/library/ms186356%28v=sql.105%29.aspx

Wednesday, November 7, 2012

TFS Aministration - How To Modify a WorkItem Type In Project A Based on Project B


I recently made a purchasing decision for our company to invest in Microsoft Test Manager. This is a shop that uses TFS for source control, work item tracking, and continuous integration. It made sense to leverage the mighty TFSWarehouse for my quality metrics as well. The down side of the decision in general is cost and complexity of administration. I am ok with the administration tasks personally, so for my team I can mitigate that concern. The value of the quality reporting solution mitigates the cost, at least at this company. I would sya that if we were using a setup like Team City (or Cruise Control), a Kanban board, and Mercurial I would be far less likely to make this same decision. The value would not be there as it would require a bunch integration patches just to execute test cases associated with automation.

A recent issue I had is the reason for this post. One team was unable to leverage the UI controls to create test steps and shared steps. I originally thought this was an issue with us working in a mixed MTM 2012 / TFS 2010 environment. It turns out the test case and shared step templates were out of date in one project. The links at the bottom of the page have all the details, but the basic work plan was:

LIST WORKITEM TYPES
PS C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE> .\witadmin listwitd /collection:http://sql1:8080/tfs/CollectionA  /p:Broken
PS C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE> .\witadmin listwitd /collection:http://sql1:8080/tfs/CollectionA  /p:Working

EXPORT WORKITEM TYPES FROM Working
PS C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE> .\witadmin exportwitd /collection:http://sql1:8080/tfs/CollectionA  /p:Working /f:c:\WorkingTestCaseSettings.xml /n:’Test Case’
PS C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE> .\witadmin exportwitd /collection:http://sql1:8080/tfs/CollectionA  /p:Working /f:c:\WorkingSharedStepsSettings.xml /n:’Shared Steps’

EXPORT WORKITEM TYPES FROM Broken
PS C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE> .\witadmin exportwitd /collection:http://sql1:8080/tfs/CollectionA  /p:Broken /f:c:\BrokenTestCaseSettings.xml /n:’Test Case’
PS C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE> .\witadmin exportwitd /collection:http://sql1:8080/tfs/CollectionA  /p:Broken /f:c:\BrokenSharedStepsSettings.xml /n:’Shared Steps’



Make a copy of the Working export files.
Change the  <GLOBALLIST name="Builds - Working" /> value to  <GLOBALLIST name="Builds - Broken" /> in the Working shared steps export file.
Change the  <GLOBALLIST name="Builds - Working" /> value to  <GLOBALLIST name="Builds - Broken" /> in the Working test case export file.

VALIDATE THE MODIFIED WORKITEM TYPES FILES
PS C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE> .\witadmin importwitd /collection:http://sql1:8080/tfs/CollectionA  /p:Broken /f:c:\BrokenTestCaseSettings.xml /v
PS C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE> .\witadmin importwitd /collection:http://sql1:8080/tfs/CollectionA  /p:Broken /f:c:\BrokenSharedStepsSettings.xml /v

IMPORT WORKITEM TYPES FROM Working TO Broken
PS C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE> .\witadmin importwitd /collection:http://sql1:8080/tfs/CollectionA  /p:Broken /f:c:\BrokenTestCaseSettings.xml
PS C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE> .\witadmin importwitd /collection:http://sql1:8080/tfs/CollectionA  /p:Broken /f:c:\BrokenSharedStepsSettings.xml

REFERENCES
http://social.msdn.microsoft.com/Forums/en-US/vsmantest/thread/6658f6e8-ab07-4579-8db0-441d322ff223
http://msdn.microsoft.com/en-us/library/dd312129%28v=vs.100%29.aspx
http://blogs.msdn.com/b/lakhminder/archive/2010/09/30/tfs-2010-enable-test-case-management-for-upgraded-team-projects.aspx


Tuesday, October 9, 2012

Microsoft Test Manager 2012 Setup

There is not much difference between 2010 and 20012 MTM. The subtle differences are covered in any number of blog posts. However I often forget what order you need to create settings when installing form scratch, hence this post.

Close visual studio
Install visual studio test edition or ultimate.
Reboot not once, but twice.
If you have not already done so, install TFS power tools to modify areas and iterations.
open test manager
create all your test plans for each project names should be meaningful from iteration to iteration if the test plans is reusable
write your test plans to be reusable as much as possible.
create a lab environment
create roles based on the environment
...stopping here as TMT 2012 does not allow environment configuration against TFS 2010.

Wednesday, September 26, 2012

CTO Interview Question Set



Have candidate describe his current role and skills
Describe our position.

Ask candidate these questions:
How do you communicate financial justifications for staffing, hardware, and software?
How do you amortize time spent developing software?
Where is the line of responsibility drawn between technical and business planning?
How do you stay current with technology innovations?
How are the acronyms API and SSO relevant to a web architecture?
What excites you about technology ?
What means do you use to measure the effectiveness of your technology department? How do you communicate that to non-technical cohorts in the c-suite or on a board of directors?
What role does a CTO play in ensuring retention of key engineering assets?
What do you communicate in a technology roadmap and who is the audience?
What is a product roadmap and how does it vary from a technology roadmap? Who is the author of each?

Monday, August 13, 2012

The Following Path Contains More than 259 Characters

There are a number of articles telling you how to reduce the path length through creative mapping (look into the \\?\ syntax). This is an issue when assemblies are gened in a long path structure.

More people need to talk about the creation of .datasource files. These suckers have a default naming convention that concatenates namespace childnamespace sub-childnamespace(n) name.datasource. This is a different issue pointed out by Praphulla Parab These are removable and avoidable.


ISSUE
These get created whenever you add a service reference to a project. These are generated automatically during the generation of the proxy class in the Reference.cs file.

This can easily make the file name lengthier than allowed. If we prefix the path to the file in the Source Control repository hierarchy, the entire path length can easily exceed the TFS 259 character limit. So far the .datasource file does not seem to be a required dependency to build the project.

RESOLUTION
Delete all datasource files and reject .datasource files in your check-in policy.  There is a trick to delete files you have not downloaded locally. Us the tf.exe tool. You must then check in the deletion of the file. Final step is to make a forbidden patterns check in policy using the regex \.datasource$ This is at the scope of the Team Project project definition.Note this is on the Team Project, so it effects everyone.

EG
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE> tf delete $<long path>/file.datasource

Thursday, August 2, 2012

Powershell Deploy Template - Set app_offline.html

#create variables for file names used in move
$hideFile = "app_offline.off.htm"
$liveFile = "app_offline.htm"

#create an array of directories you want to swap files in
$path = @(
"C:\InetPub\Site1"
,"C:\InetPub\Site2"
,"C:\InetPub\Site3"
)

#counters for while loop based on number of directories
#NOTE: Count enumerates from 1. array position enumerates from 0
$maxCnt = $path.Count
$currCnt = 0

#create a log
$logFile = "\temp.txt"
Set-Variable -name log -value $env:userprofile$logFile
if (Test-Path $log) {rm $log}
New-Item $log -type file

#set-variable was used to construct the path due to errors I was getting calling the path and file variables on the fly
#NOTE: Count enumerates from 1. array position enumerates from 0
while ($currCnt -lt $maxCnt)

{
Set-Variable -name currPath -value $path[$currCnt.ToString()]
;  Set-Variable -name hidePath -value $currPath$hideFile
;  Set-Variable -name livePath -value $currPath$liveFile
;  Set-Variable -name currTime -value (Get-Date)
; Move-Item $hidePath  $livePath >> $log
; echo "$currTime moved $hidePath to $livePath"  >> $log
; $currCnt = $currCnt +1
}

Thursday, July 5, 2012

T-SQL - Common Table Expressions are as Performant as Inline Tables

Common table expressions are as performant as inline table queries. This was something I have to prove to myself. I ran the same query written both as an inline table and CTE several times. for 629,000 rows I had the same execution time (13 seconds) every single time with both queries. The query plan was identical, down to the the estimate total subtree cost for each operation. The advantage for a CTE comes out in iterative processing and a cleaner style (in my opinion).


EXAMPLE 1
SELECTMIN(a.Date1) AS Date1,a.PersonIDFROM(SELECT DISTINCTDate1,PersonIDFROMTable2UNIONSELECT DISTINCTDate1,OtherPersonID AS PersonIDFROMTable1

) AS aLEFT JOIN Table3 (nolock) AS bON (ISNULL(a.PersonID,'?') = b.SomeKey SomeKey)
WHERE b.SomeKey IS NULL
GROUP a

EXAMPLE 2
WITHa AS(SELECT DISTINCTDate1,PersonIDFROMTable2UNION SELECT DISTINCT Date1,OtherPersonID AS PersonID FROMTable1

) SELECT MIN(a.Date1) AS Date1,a.PersonID

FROM a LEFT JOIN Table3 (nolock) AS b ON (ISNULL(a.PersonID,'?') = b.SomeKey )WHERE b.SomeKey IS NULL
GROUP a BY .PersonID BY .PersonID

Friday, June 22, 2012

A Little More Dynamic SQL - Condtitional WHERE

/*
TEST: Find Data
*/
--create a table variable to store the source/target mappings
DECLARE
@SourceTarget Table(ID INT Identity (1,1),TargetServer nVarchar(300),TargetDB nVarchar(300),TargetSchema nVarchar(300),TargetTable nVarchar(300),SourceServer Nvarchar (300),SourceDB nVarchar(300),SourceSchema nVarchar(300),SourceTable nVarchar(300),SourceKeyCols nVarchar(300),TrgKeyCols nVarchar(300))
--populate the table with the ETL table mappings for this project
INSERT INTO @SourceTarget(TargetServer ,TargetDB ,TargetSchema ,TargetTable,SourceServer ,SourceDB ,SourceSchema ,SourceTable
)
VALUES
(
(
'SERVER','DATABASE','dbo','Table1','Server2','databse2','schema','Table1.1'),'SERVER','DATABASE','dbo','Table2','Server2','databse2','schema','Table2.1')
--Declare the variables used in the test
DECLARE
@StartCnt
INT = 1,@MaxCnt INT = (SELECT COUNT (1) FROM @SourceTarget),@SourceServer nVarchar(100),@SourceDB nVarchar(100),@SourceSchema nVarchar(100),@SourceTable nVarchar(100),@TargetServer nVarchar(100),@TargetDB nVarchar(100),@TargetSchema
@TargetTable
nVarchar(100), nVarchar(100),@Today nVarchar(8),
--used to dynamically determine the column names for the row meta data
@Where nVarchar(MAX),
--use for creating the dynamic SQL
@sql
nVarchar(MAX)
WHILE
@StartCnt <= @MaxCnt
BEGIN
--set the values for each four part table name we want to testSET @SourceServer = (SELECT SourceServer FROM @SourceTarget WHERE ID = @StartCnt)SET @SourceDB = (SELECT SourceDB FROM @SourceTarget WHERE ID = @StartCnt)SET @SourceSchema = (SELECT SourceSchema FROM @SourceTarget WHERE ID = @StartCnt)SET @SourceTable = (SELECT SourceTable FROM @SourceTarget WHERE ID = @StartCnt)SET @TargetServer = (SELECT TargetServer FROM @SourceTarget WHERE ID = @StartCnt)SET @TargetDB = (SELECT TargetDB FROM @SourceTarget WHERE ID = @StartCnt)SET @TargetSchema = (SELECT TargetSchema FROM @SourceTarget WHERE ID = @StartCnt)SET @TargetTable = (SELECT TargetTable FROM @SourceTarget WHERE ID = @StartCnt)SET @Today = (SELECT CONVERT(CHAR(8), GetDate(), 112))IF @SourceTable IN ('table1')
BEGIN SET @Where = 'WHERE Created_Date > '''
SET @Where = @Where + @TodaySET @Where = @Where + ''' '
and DATEPART(mm, Created_Date) = DATEPART(mm, Updated_Date)
and DATEPART(yy, Created_Date) = DATEPART(YY, Updated_Date)'
SET @Where = @Where + 'and DATEPART(dd, Created_Date) = DATEPART(dd, Updated_Date)

ELSE
IF
END @SourceTable IN ('tabel2')
BEGINSET @Where = 'WHERE created_date > '''
SET @Where = @Where + @Today SET @Where = @Where + ''' '
and DATEPART(mm, Created_date) = DATEPART(mm, Updated_date)
and DATEPART(yy, Created_date) = DATEPART(YY, Updated_date)'
SET @Where = @Where + 'and DATEPART(dd, Created_date) = DATEPART(dd, Updated_date)

ELSE
END
BEGINSET @Where = 'WHERE createdDate > '''
SET @Where = @Where + @TodaySET @Where = @Where + ''' '
DATEPART(dd, CreatedDttm) = DATEPART(dd, UpdatedDttm)
AND DATEPART(mm, CreatedDttm) = DATEPART(mm, UpdatedDttm)
AND DATEPART(yy, CreatedDttm) = DATEPART(YY, UpdatedDttm)
)
OR (
DATEPART(dd, CreatedDttm) = DATEPART(dd, DeletedDttm)
AND DATEPART(mm, CreatedDttm) = DATEPART(mm, DeletedDttm)
AND DATEPART(yy, CreatedDttm) = DATEPART(YY, DeletedDttm)
)
OR (
DATEPART(dd, UpdatedDttm) = DATEPART(dd, DeletedDttm)
AND DATEPART(mm, UpdatedDttm) = DATEPART(mm, DeletedDttm)
AND DATEPART(yy, UpdatedDttm) = DATEPART(YY, DeletedDttm)
)
'
SET @Where = @Where + 'AND (
END
SET @sql = ' + @SourceServer + '.' + @SourceDB + '.' + @SourceSchema + '.' + @SourceTable+ space(1) + 'WITH (NOLOCK) '


'
+ space(1) + @Where + '


PRINT
EXEC sp_executesql @sql OUTPUT @Today PRINT @WhereSET @StartCnt = @StartCnt +1;END

SELECT * FROM '