VB.Net Method似乎在实际上不被调用时多次调用,并返回不一致的结果

时间:2014-07-11 18:07:32

标签: tfs2010 vb.net-2010 tfsbuild

我整天都在盯着这个问题而且我完全被我所看到的东西困惑。 发生了两个问题,不幸的是,其中一个只发生在生产中,所以我无法按照我喜欢的方式进行测试。

我将在最后提供所有背景和相关信息。在您查看代码之前,我在接下来的几个部分中所说的一些内容将没有多大意义。

背景信息:
(我已经三重验证了所有这些信息)

  1. 从TFS 2010 WWF构建模板调用此类。它依赖于我在另一个工具中创建的库,使用UniDK将文件部署到我们的Universe环境
  2. 部署本身运行正常,问题在于日志记录和返回代码。
  3. 如果下面的类返回0代码,“Partial Success”返回代码为1,则生成标记为“Success”,如果有任何其他返回代码,则生成“失败”。
  4. 文件只被部署一次(objDeploy.DeployFiles()只调用一次)
  5. serverInfo.ServerCount = 2
  6. 第二个环境的serverInfo.ServerActive(counter = 1)为False
  7. 为了帮助追踪问题,我在ProcessResults()中添加了额外的日志记录,以将不同集合的值输出到单独的文件中,但我没有机会使用附加代码运行它
  8. 症状:

    1. 在制作中,退出时返回代码为1(e​​xitCode = 1)
    2. 这是结果字符串返回的内容:
    3.   

      服务器名称的结果已成功部署!
        ***********************
      服务器名称的结果
      部署成功!
        ***********************
      服务器名称的结果
      部署错误,请查看日志
        ***********************
      服务器名称的结果
      部署成功!
        ***********************
      服务器名称的结果
      部署成功!
        ***********************
         3.在QA中,我们有6次“服务器名称的结果”消息,但每次都说部署成功了    4.部署日志文件中的所有内容都显示已部署的所有文件的代码均为0(这意味着Result40Collection,BackupErrorCollection和BadErrorCollection应为空。我将在稍后解释为什么这一点特别重要)

      我期待发生的事情:

      1. exitCode = 0
      2. Build = succeeded
      3. 结果:
      4.   

        服务器名称的结果已成功部署!
          ***********************

        我希望根据TFS构建日志中的结果发生什么: 在本节中,我忽略了这样一个事实,即返回了多个条目,并且仅关注那些表示存在错误的条目

        1. exitCode = 2
        2. 构建=失败
        3. 结果:
        4.   

          服务器名称的结果是部署错误,请查看日志   
            ***********************

          代码:

          Imports System
          Imports Microsoft.TeamFoundation.Build.Client
          Imports System.Activities
          Imports RMUtilities
          
          <BuildActivity(HostEnvironmentOption.All)>
          Public NotInheritable Class DeployU2Files
              Inherits CodeActivity
          
          #Region "Arguments"
          
              ' In Arguments
              Property inServerDataSet As InArgument(Of DataSet)  ' Dataset containing the server information
              Property inSourcesDirectory As InArgument(Of String)  ' Full path to the Source directory being deployed
              Property inBuildName As InArgument(Of String) ' Name of the build, to be used for backups
              Property inLogDirectory As InArgument(Of String) ' Path to the log folder
          
              ' Out Arguments
              Property outExitCode As OutArgument(Of Integer) ' Resulting error code, 0 is good
              Property outResult As OutArgument(Of String)     ' Result string
          
          #End Region ' "Arguments"
          
          #Region "Variables"
          
              ' Variables passed in from the build
              Dim dsServerDataSet As DataSet
              Dim strSourcesDirectory As String
              Dim strBuildName As String
              Dim strLogDirectory As String
          
              ' Variables used by the build
              Dim serverInfo As XMLReader
              Dim fileList As U2FileListParser
          
              ' Result variables
              Dim exitCode As Integer = 0
              Dim results As String = ""
          
          #End Region '"Variables"
          
              Protected Overrides Sub Execute(context As System.Activities.CodeActivityContext)
          
                  ' Sets the working variables
                  dsServerDataSet = context.GetValue(Me.inServerDataSet)
                  strSourcesDirectory = context.GetValue(Me.inSourcesDirectory)
                  strBuildName = context.GetValue(Me.inBuildName)
                  strLogDirectory = context.GetValue(Me.inLogDirectory)
          
                  ' Creates the base objects needed for the deployment
                  Try
                      serverInfo = New XMLReader(dsServerDataSet)
                      fileList = New U2FileListParser(strSourcesDirectory)
                  Catch ex As NullReferenceException
                      Throw New NullReferenceException("Invalid XML Dataset", ex)
                      Exit Sub
                  Catch ex As Exception
                      Throw New Exception("Error processing file list: " & ex.Message, ex)
                  End Try
          
                  ' First, determine if there are files to deploy
                  Dim fileCount As Integer
                  Try
                      With fileList
                          fileCount = .DeployList.Count + .PreDeployList.Count + .PostDeployList.Count
                      End With
                  Catch ex As Exception
                      Throw New ArgumentException("No files to deploy")
                  End Try
                  If fileCount = 0 Then Throw New ArgumentException("No files to deploy")
          
                  ' Then, check to make sure there are servers to deploy to
                  If serverInfo.ServerCount = 0 Then
                      Throw New ArgumentException("No servers listed in XML file to deploy to")
                  End If
          
                  ' Iterates through each server in the XML file
                  For counter = 0 To serverInfo.ServerCount - 1
          
                      ' Sets the current environment
                      serverInfo.ChosenEnvironment = counter
          
                      ' Checks to make sure the server is active.  If it isn't, it's skipped
                      If serverInfo.ServerActive Then
          
                          ' Creates new logging object to log all output to a file with the name of the server being deployed to
                          Dim logger = New RMLogging(strLogDirectory & "\" & serverInfo.ServerHostName & ".log")
                          logger.Header = "Automated deploy" & vbCrLf & _
                              "Build Number: " & strBuildName & vbCrLf & _
                              "Date: " & DateTime.Now.ToString("MMM ddd d yyyy hh:mm:ss tt")
          
                          ' Creates the deployment object
                          Dim objDeploy As New U2Deploy(serverInfo, fileList, logger, strBuildName)
          
                          ' Deploys the files to the environment, then checks the results to make sure they
                          objDeploy.DeployFiles()
          
                          ' This will determine the success level of the deployment, and also parses the message for the log
                          ProcessResults(objDeploy, serverInfo.ServerHostName)
          
                          ' If there was a problem writing the log, then add the full text of the log to the results
                          If objDeploy.FullLog.Length > 0 Then
                              results &= objDeploy.FullLog & vbCrLf
                              results &= "**********************************" & vbCrLf
                          End If ' objDeploy.FullLog.Length > 0
          
                          ' Disposes the objects
                          logger = Nothing
                          objDeploy.Clear()
                          objDeploy = Nothing
          
                      End If ' serverInfo.ServerActive
          
                  Next ' counter = 0 To serverInfo.ServerCount - 1
          
                  SetResults(exitCode, results, context)
          
              End Sub
          
              ''' <summary>
              ''' Will change the exite code based on the results of the deployment
              ''' </summary>
              ''' <param name="objDeploy">U2Deploy object that contains the collections</param>
              ''' <remarks></remarks>
              Private Sub ProcessResults(objDeploy As U2Deploy, serverName As String)
          
                  Dim currentErrorCode As Integer = 0
          
          
                  results &= "Results for " & serverName & vbCrLf
          
                  If objDeploy.Result40Collection.Count() > 0 Then
                      currentErrorCode = 1
                      results &= "Type 40 errors, please review the log" & vbCrLf
                  End If ' objDeploy.Result40Collection.Count() > 0
          
                  If objDeploy.BackupErrorCollection.Count > 0 Then
                      currentErrorCode = 1
                      results &= "File backup errors, please review the log" & vbCrLf
                  End If ' objDeploy.BackupErrorCollection.Count > 0
          
                  If objDeploy.BadErrorCollection.Count > 0 Then
                      currentErrorCode = 2
                      results &= "Deployment errors, please review the log" & vbCrLf
                  End If
          
                  If currentErrorCode = 0 Then results &= "Deployment successful!" & vbCrLf
          
                  results &= "***********************" & vbCrLf
          
                  If currentErrorCode > exitCode Then exitCode = currentErrorCode
              End Sub
          
              ' Sets the outgoing message and exit code.  This is used by the workflow to add messages to the buld itself
              Private Sub SetResults(ByVal exitCode As Int32, message As String, ByRef context As CodeActivityContext)
          
                  context.SetValue(Me.outExitCode, exitCode)
                  context.SetValue(Me.outResult, message)
          
              End Sub
          End Class
          

          更新 我已经能够在启用详细日志记录的情况下在QA中运行两次,这是结果(再次,完全不一致)。我只使用VS2013查看和运行构建,构建使用的类的任何代码更改都在VS2010中完成。

          运行1: enter image description here

          运行2: enter image description here

1 个答案:

答案 0 :(得分:1)

我实际上昨晚刚解决了这个问题。问题实际上是我在WWF流程上阅读的文档。这段代码实际上是正确执行的,并返回了正确的值,但由于指令不正确,它在工作流程中采用了错误的路径,这使得该代码显示错误。

在诊断日志记录打开的情况下,我花了一段时间再次发生此错误,一旦我看到它,我立即知道问题是什么。

根本原因是我认为WriteBuildError会将构建标记为Failed,而是将其标记为Partially Succeeded,这使我进入了错误的故障排除路径。