Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allure TeamCity plugin locks file #80

Closed
2 tasks
imanushin opened this issue Nov 26, 2018 · 20 comments
Closed
2 tasks

Allure TeamCity plugin locks file #80

imanushin opened this issue Nov 26, 2018 · 20 comments

Comments

@imanushin
Copy link

I'm submitting a ...

  • [V] bug report
  • feature request
  • support request => Please do not submit support request here, see note at the top of this template.

What is the current behavior?

Allure TeamCity plugin step locks files in the my-application/allure-results folder. So next build could not checkout git folder, because directory is used

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem

  • Create TeamCity build with "VCS checkout mode:" always checkout on agent.
  • Add new step for this build:
    • Runner type: Allure Report
    • Step name: Allure report
    • Execute step: even if some of the previous steps failed
    • Allure result directory: my-application/allure-results/
    • Report artifacts subdirectory: my-application/allure-report/
  • Execute TeamCity build (with the step above)
  • Execute the same build on the same agent
    • As a result - git was not able to do clean checkout, because ``my-application/allure-results/``` is used by team city agent (e.g. some code from TeamCity agent opened file from the target folder and did not close it)

What is the expected behavior?

TeamCity builds can be executed on the same agent without agent restart.

What is the motivation / use case for changing the behavior?

This behavior prevents Allure Report runner type usage, because agent has to be restarted after first Allure Report usage.

Please tell us about your environment:

Allure version 2.7.0
Test framework jest@22.4.4
Allure adaptor jest-allure@0.0.2
Generate report using allure-teamcity@2.7

Other information

@zarseny
Copy link

zarseny commented Dec 3, 2018

Temporary workaround - killing processes with swabra.

@AdrianJetzer
Copy link

Hi
I'm having the exact same issue. In my case applying swabra does not help.
Is there a fix planned for this issue?
Thanks
Adrian

@imanushin
Copy link
Author

Temporary workaround - killing processes with swabra.

Process it locked by TeamCity agent itself. So swabra will interrupt build in this case.

@alexiuss
Copy link

alexiuss commented Feb 5, 2019

Hi,
Confirm the same behavior as OP described.
Allure version 2.9.0
Killing agent's java process itself helps, but it's not the way for CI/CD

@konstest
Copy link

Hi, i have the same problem.
My environment:

  • TeamCity server 2018.2 (build 60925)
  • Allure Plugin version: 2.9.0

Somebody can tell me workaround this problem?

p.s. on TeamCity Allure plugin 2.6 all worked all right

@konstest
Copy link

konstest commented Jun 28, 2019

I found workaround this problem that not require killing TC agent.
Download SystemInternalSuite (https://docs.microsoft.com/en-us/sysinternals/downloads/) and uses Handle.exe:

> C:\tools\SysinternalsSuite\Handle.exe E:\BuildAgent\work\c551c076fefe7f0e /accepteula
E:\BuildAgent\work\c551c076fefe7f0e Handle this processes:

Handle v4.0
Copyright (C) 1997-2014 Mark Russinovich
Sysinternals - www.sysinternals.com

java.exe           pid: 11576  type: File          1294: E:\BuildAgent\work\c551c076fefe7f0e\SRC\history
java.exe           pid: 11576  type: File          13A8: E:\BuildAgent\work\c551c076fefe7f0e\SRC\history
powershell.exe     pid: 19028  type: File            40: E:\BuildAgent\work\c551c076fefe7f0e
handle.exe         pid: 13520  type: File            8C: E:\BuildAgent\work\c551c076fefe7f0e
Handle64.exe       pid: 10424  type: File            50: E:\BuildAgent\work\c551c076fefe7f0e

> C:\tools\SysinternalsSuite\Handle.exe -p 11576 -c 1294 -y -accepteula

Handle v4.0
Copyright (C) 1997-2014 Mark Russinovich
Sysinternals - www.sysinternals.com

 1294: File  (RWD)   E:\BuildAgent\work\c551c076fefe7f0e\SRC\history

Handle closed.

> C:\tools\SysinternalsSuite\Handle.exe -p 11576 -c 13A8 -y -accepteula

Handle v4.0
Copyright (C) 1997-2014 Mark Russinovich
Sysinternals - www.sysinternals.com

 13A8: File  (RWD)   E:\BuildAgent\work\c551c076fefe7f0e\SRC\history

Handle closed.

You can create your custom TC metaranner https://teamcity.your-domain.com/admin/editProject.html?projectId=_Root&tab=metaRunner the following content:

<?xml version="1.0" encoding="UTF-8"?>
<meta-runner name="PT-runner: Closing Allure Report handlers">
  <description>Hack on PowerShell. Closing handlers on directories opened by Allure Plugin.</description>
  <settings>
    <parameters>
      <param name="WorkDirectory" value="%system.teamcity.build.checkoutDir%" spec="text description='Change working directory. Relative from checkout dir.' display='normal' label='Working Directory:'" />
    </parameters>
    <build-runners>
      <runner id="CloseAllureReportHandlers" name="" type="jetbrains_powershell">
        <parameters>
          <param name="jetbrains_powershell_execution" value="PS1" />
          <param name="jetbrains_powershell_noprofile" value="true" />
          <param name="jetbrains_powershell_script_mode" value="CODE" />
          <param name="teamcity.step.mode" value="default" />
          <param name="jetbrains_powershell_edition" value="Desktop" />
          <param name="jetbrains_powershell_script_code"><![CDATA[Add-Type -AssemblyName System.IO.Compression.FileSystem
function Unzip
{
    param([string]$zipfile, [string]$outpath)
    [System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath)
}

Function Close-LockedFile{
Param(
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)][String[]]$Filename
)
Begin{
    $ToolsDir = "C:\tools"
	$SSuiteDir = "$ToolsDir\SysinternalsSuite"
    $HandleApp = "$SSuiteDir\Handle.exe"
    If(!(Test-Path $HandleApp)){
        Write-Host "Handle.exe is not found at $HandleApp, download him."
        if(!(Test-Path -Path $ToolsDir )){
            Write-Host "Create dir: $ToolsDir"
            New-Item -ItemType directory -Path $ToolsDir
        }
        
        $ToolsUrl = "https://download.sysinternals.com/files/SysinternalsSuite.zip"
        $ToolsZip = "$ToolsDir\SysinternalsSuite.zip"
        
        if(!(Test-Path -Path $ToolsZip )){
            Write-Host Download $ToolsUrl to $ToolsZip
            $start_time = Get-Date
            $i = 1
            $Attempts = 3
            While ($true) {
                if ( $i -gt $Attempts ) { 
                    Write-Host "Can not download $tools_url"
                    exit 1
                }
                Try {
            	    (New-Object System.Net.WebClient).DownloadFile($ToolsUrl, $ToolsZip)
            	    break
                }
                Catch { Write-Host Attempt to download: $i }
                $i++
            }
            Write-Output "Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)"
        }
        
        if(!(Test-Path -Path $SSuiteDir )){
            Write-Host Unarchiving $ToolsZip to $SSuiteDir
            Unzip $ToolsZip $SSuiteDir
        } else {
            Write-Host Remove old breakable $SSuiteDir
            Remove-Item -Path $SSuiteDir -Force -Recurse -ErrorAction SilentlyContinue

            Write-Host Unarchiving $ToolsZip to $SSuiteDir
            Unzip $ToolsZip $SSuiteDir
        }
    }
}

Process{
    Write-Host ("*"*80)
    Write-Host "BEFORE close handlers"
    $HandleOut = Invoke-Expression ($HandleApp+' '+$Filename + '  /accepteula')
    Write-Host "$Filename Handle this processes:"
    echo $HandleOut
    Write-Host ("*"*80)

    Write-Host "Try to close all handlers who are having opened files in $Filename"
    $Locks = $HandleOut |?{$_ -match "(.+?)\s+pid: (\d+?)\s+type: File\s+(\w+?): (.+)\s*$"}|foreach{
        [PSCustomObject]@{
            'AppName' = $Matches[1]
            'PID' = $Matches[2]
            'FileHandle' = $Matches[3]
            'FilePath' = $Matches[4]
        }
    }

    ForEach($Lock in $Locks){
        Write-Host ""
        Write-Host ("-"*40)
        Write-Host $Lock.AppName 
        if ($lock.AppName -like "*powershell*" -or $lock.AppName -like "*handle*")
        {
            Write-Host "Skip kill..." 
            Write-Host ("-"*40)
            continue
        }
        # Close handlers on files/directories
        $command = ($HandleApp + " -p " + $Lock.PID + " -c " + $Lock.FileHandle + " -y -accepteula")
        Write-Host $command
        Invoke-Expression $command -Verbose
        If ( ! $LastexitCode ) { Write-Host "Successfully closed"} else {Write-Host "Handle closed ERROR"}

        Write-Host ("-"*40)
    }
}

End{
    Write-Host ("*"*80)
    Write-Host "AFTER CLOSE HANDLERS"
    $HandleOut = Invoke-Expression ($HandleApp+' '+$Filename)
    Write-Host "$Filename Handle this processes:"
    echo $HandleOut
    Write-Host ("*"*80)
}
}

Close-LockedFile "%WorkDirectory%"]]></param>
        </parameters>
      </runner>
    </build-runners>
    <requirements />
  </settings>
</meta-runner>

And then uses it into your custom TC configurations after Allure Report build step.

@Manishabarhate
Copy link

I am having exactly same issue.. following

@solazs
Copy link

solazs commented Nov 5, 2019

We are also hitting this issue big time, and honestly, having a metarunner for this is so hacky it is not even fun. Sub.

@oolkhovoy
Copy link

+1 on this

1 similar comment
@remote-specialist
Copy link

+1 on this

@alex-dylda
Copy link

have the same problem

@Silencegod
Copy link

Silencegod commented Jan 23, 2020

I got the same problem with windows agents. Java process on agent still use fork/allure-results/history/ even if previous build has been successful. Next build running on the same agent will fail with error: "C:\Program Files\Git\bin\git.exe" clean -f -d -x' command failed. exit code: 1 stderr: warning: could not open directory 'fork/allure-results/history/': Permission denied warning: failed to remove fork/allure-results/history: Directory not empty
I can fix this problem by killing java process manually but it need to be done on every build.

@alex-dylda
Copy link

@Silencegod you can kill java process not manually but as @konstest provided above (his powershell code works properly). It helped me (thanks @konstest a lot).
If you don't want to create meta runner in Team City you can just create Powershell step after Allure-report step and add there powershell code (before this don't forget to download SystemInternalSuite (https://docs.microsoft.com/en-us/sysinternals/downloads/) and extract Handle.exe to folder that Team city can use it). I did it that way:

$Filename = "<Path To Allure-Results Folder>\history"
$HandleApp = "<Path To Handle.exe>\Handle.exe"
Write-Host ("*"*80)
Write-Host "BEFORE close handlers"
$HandleOut = Invoke-Expression ($HandleApp+' '+$Filename + '  /accepteula')
Write-Host "$Filename Handle this processes:"
echo $HandleOut
Write-Host ("*"*80)

Write-Host "Try to close all handlers who are having opened files in $Filename"
$Locks = $HandleOut |?{$_ -match "(.+?)\s+pid: (\d+?)\s+type: File\s+(\w+?): (.+)\s*$"}|foreach{
    [PSCustomObject]@{
        'AppName' = $Matches[1]
        'PID' = $Matches[2]
        'FileHandle' = $Matches[3]
        'FilePath' = $Matches[4]
    }
}

ForEach($Lock in $Locks){
    Write-Host ""
    Write-Host ("-"*40)
    Write-Host $Lock.AppName 
    if ($lock.AppName -like "*powershell*" -or $lock.AppName -like "*handle*")
    {
        Write-Host "Skip kill..." 
        Write-Host ("-"*40)
        continue
    }
    # Close handlers on files/directories
    $command = ($HandleApp + " -p " + $Lock.PID + " -c " + $Lock.FileHandle + " -y -accepteula")
    Write-Host $command
    Invoke-Expression $command -Verbose
    If ( ! $LastexitCode ) { Write-Host "Successfully closed"} else {Write-Host "Handle closed ERROR"}

    Write-Host ("-"*40)
}

Write-Host ("*"*80)
Write-Host "AFTER CLOSE HANDLERS"
$HandleOut = Invoke-Expression ($HandleApp+' '+$Filename)
Write-Host "$Filename Handle this processes:"
echo $HandleOut
Write-Host ("*"*80)

Here you just need to replace <Path To Allure-Results Folder> and <Path To Handle.exe> with your values. Other code should not be touched.

@imanushin
Copy link
Author

@alex-dylda, killing process is invalid solution. Holding process is Teamcity Agent. If you kill it then build will be stopped too.

Also killing processes because developers are unable to close resources isn't a good practice.

@alex-dylda
Copy link

@imanushin

killing process is invalid solution. Holding process is Teamcity Agent. If you kill it then build will be stopped too.

If you read carefully you could see that agent process will not be killed only java handles that locking the file will be killed, so it would not interrupt agent work.
You could try the fix before writing this comment and confusing others.

Also killing processes because developers are unable to close resources isn't a good practice.
Thanks for advise. If you know how to fix it then please fix.

This a temporary workaround while the bug with locking folder will not be fixed (maybe it will never be fixed). It's a pitty but I don't know how to fix the bug, so this fix helps me now.

@imanushin
Copy link
Author

@alex-dylda, yes, agree. I'm still not sure that handle killing is safe (because there aren't proofs that handle isn't really needed). However you are right, this operation doesn't touch TC Agent.

@alex-dylda
Copy link

@imanushin, I agree that this can be unsafe, but I use it for couples of weeks and for a while no problems. Once fix will be implemented I will remove this step with a great pleasure)

@MistaCheese
Copy link

  • 1 bag

@qww-tmp
Copy link

qww-tmp commented May 17, 2020

If you don't want to create meta runner in Team City you can just create Powershell step after Allure-report step and add there powershell code (before this don't forget to download SystemInternalSuite (https://docs.microsoft.com/en-us/sysinternals/downloads/) and extract Handle.exe to folder that Team city can use it). I did it that way:

@alex-dylda But, it will be work only if you start this task in agents with system user, otherwise, even if you admin, UAC control process, and you can't kill it.
m.b. some one can fix this issue? :(

@ivan1767p
Copy link
Contributor

Please review PR. I added try-with-resources statement for Files.list. It's need for close stream.

@baev baev closed this as completed in 4f826ed Jun 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests