stryker-mutator / stryker-net

Mutation testing for .NET core and .NET framework!
https://stryker-mutator.io
Apache License 2.0
1.77k stars 184 forks source link

Compile error: The name 'ThisAssembly' does not exist in the current context (Source code: ThisAssembly) #2393

Closed ThompsonNye closed 2 months ago

ThompsonNye commented 1 year ago

Describe the bug I was testing Stryker to prepare for integrating it in out GitLab CI/CD pipeline. Running Stryker succeeds on my laptop which is running Windows, but fails in various Docker containers on a Linux server host which resembles the environment of the CI/CD pipeline.

The error message is: Stryker.NET encountered an compile error in /code/src/Bechtle.OmniSys.Api/Startup.cs (at 34:24) with message: The name 'ThisAssembly' does not exist in the current context (Source code: ThisAssembly) This error message comes from the tool Nerdbank.GitVersioning. The Nerdbank.GitVersioning generates the class ThisAssembly with compile time constants calculated based in the git history. Judging from the line number, the error probably occurs when setting the version and title in the swagger configuration.

Having the tool Nerdbank.GitVersioning installed (tried both global and local install) has no effect on running Stryker. When installed, the tool returns the current version information as expected. A regular dotnet build succeeds with and without the tool having been explicitly installed. All tests (unit + integration tests) succeed when simply executed with dotnet test.

Logs log-20230131.txt The log is quite long (13k lines). Please let me know if you need something different and what I need to do to generate that.

Expected behavior The test runs succeed in a Docker container just like they do on Windows.

Server / Docker images

dupdob commented 1 year ago

I do not think the problem is related to Docker. I suspect you will face the same issue on a clean project. Alas, Stryker can not support custom built steps, so if your build generates a file via some user defined ms Jim's task/external tool, it will be skipped.

I think it works on your machine because the file has already been generated and can be reused.

If this is the case, the best workaround is to rely on a Roslyn code generator instead (those are supported). Alternatively, you can ensure the generated file is present.

This is my best guess for the moment.

ThompsonNye commented 1 year ago

Thanks for your reply.

I have verified that Stryker works on a newly cloned project on my Windows machine, even without having built or restored it before running Stryker. It does not work in the mentioned Docker containers, both on a Linux Server host as well as on my Windows machine, both with and without building it beforehand.

The class ThisAssembly is generated by the Nerdbank.GitVersioning nuget package as part of the regular build process. I am not generating anything via a custom job beforehand. For example, the relevant part of my Dockerfile targeting the dotnet/sdk:6.0-alpine image is:

COPY ["nuget.config", "."]
COPY ["src/Api/Api.csproj", "Api/"]
RUN dotnet restore "Api/Api.csproj"
COPY . .
WORKDIR "/src/src/Api"
RUN dotnet build "Api.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Api.csproj" -c Release -o /app/publish /p:UseAppHost=false

Unfortunately, I cannot share the project because it is an internal project. And I do not have the time to recreate the problem in a new project (simply creating a new project Web API project with an xunit test project and using the ThisAssembly class does not result in the error described above).

Workaround:

Since I only use the ThisAssembly class in two places, I have for now implemented a workaround which simply replaces the parts in the source code with values manually extracted via the dotnet nbgv cli tool before running dotnet stryker:

aiv=$(dotnet nbgv get-version --format json | jq -r '.AssemblyInformationalVersion')
sed -i "s/ThisAssembly.AssemblyInformationalVersion/\"$aiv\"/" src/Api/Startup.cs
sed -i "s/ThisAssembly.RootNamespace/\"Api\"/" src/Api/Startup.cs
dotnet stryker

I hope I can provide a simple project showcasing the error, once I have some more time.

dupdob commented 1 year ago

I have yet to understand while it works on new project, but Stryker does not support custom tasks, and NerdBank.GitVersioning does rely on a custom task to generate the assembly info file. So manually generating the file before launching Stryker is the proper workaround indeed. The actual limitations is hard to address, sadly.

dupdob commented 2 months ago

this issue has probably been fixed thanks to an update in how needed source files are identified during project analysis. I am closing this issue assuming it is actually fixed. Feel free to reopen it if the problem is still present