Description
When doing integration tests with a dotnet sdk alpine image, I get the error that it can't find the chrome-linux directory.
\u001b[41m\u001b[30mfail\u001b[39m\u001b[22m\u001b[49m: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.AggregateException: One or more errors occurred. (An error occurred trying to start process '/builds/test/ClientReportConclusionDrawer.Graph.Tests/bin/Release/net6.0/.local-chromium/Linux-884014/chrome-linux/chrome' with working directory '/builds/test/ClientReportConclusionDrawer.Graph.Tests/bin/Release/net6.0'. No such file or directory)
---> System.ComponentModel.Win32Exception (2): An error occurred trying to start process '/builds/test/ClientReportConclusionDrawer.Graph.Tests/bin/Release/net6.0/.local-chromium/Linux-884014/chrome-linux/chrome' with working directory '/builds/test/ClientReportConclusionDrawer.Graph.Tests/bin/Release/net6.0'. No such file or directory
at System.Diagnostics.Process.ForkAndExecProcess(ProcessStartInfo startInfo, String resolvedFilename, String[] argv, String[] envp, String cwd, Boolean setCredentials, UInt32 userId, UInt32 groupId, UInt32[] groups, Int32& stdinFd, Int32& stdoutFd, Int32& stderrFd, Boolean usesTerminal, Boolean throwOnNoExec)
at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start()
at PuppeteerSharp.States.ChromiumStartingState.StartCoreAsync(LauncherBase p) in C:\projects\puppeteer-sharp\lib\PuppeteerSharp\States\ChromiumStartingState.cs:line 68
at PuppeteerSharp.Launcher.LaunchAsync(LaunchOptions options) in C:\projects\puppeteer-sharp\lib\PuppeteerSharp\Launcher.cs:line 68
at PuppeteerSharp.Launcher.LaunchAsync(LaunchOptions options) in C:\projects\puppeteer-sharp\lib\PuppeteerSharp\Launcher.cs:line 91
--- End of inner exception stack trace ---
at Microsoft.FSharp.Control.AsyncResult`1.Commit() in D:\a\_work\1\s\src\fsharp\FSharp.Core\async.fs:line 391
at Microsoft.FSharp.Control.AsyncPrimitives.RunImmediate[a](CancellationToken cancellationToken, FSharpAsync`1 computation) in D:\a\_work\1\s\src\fsharp\FSharp.Core\async.fs:line 1063
at Microsoft.FSharp.Control.AsyncPrimitives.RunSynchronously[T](CancellationToken cancellationToken, FSharpAsync`1 computation, FSharpOption`1 timeout) in D:\a\_work\1\s\src\fsharp\FSharp.Core\async.fs:line 1069
at Microsoft.FSharp.Control.FSharpAsync.RunSynchronously[T](FSharpAsync`1 computation, FSharpOption`1 timeout, FSharpOption`1 cancellationToken) in D:\a\_work\1\s\src\fsharp\FSharp.Core\async.fs:line 1365
at ClientReportConclusionDrawer.Graph.Services.GraphService.<>c__DisplayClass2_0.<GenerateGaugeGraph>b__0() in /builds/src/ClientReportConclusionDrawer.Graph/Services/GraphService.cs:line 32
at System.Threading.Tasks.Task`1.InnerInvoke()
at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj)
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
at ClientReportConclusionDrawer.Graph.Services.GraphService.GenerateGaugeGraph(Double score, Int32 width, Int32 height, Int32 dpi, Int32 margin, Tuple`2 range, SupportedImageTypes imageType) in /builds/src/ClientReportConclusionDrawer.Graph/Services/GraphService.cs:line 27
at ClientReportConclusionDrawer.Graph.Controllers.GraphController.GaugeGraph(GraphRequest request) in /builds/src/ClientReportConclusionDrawer.Graph/Controllers/GraphController.cs:line 20
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
When using a custom Docker image installing pupeteer on it, I get a different error saying something about an unhandled exception:
\u001b[41m\u001b[30mfail\u001b[39m\u001b[22m\u001b[49m: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.AggregateException: One or more errors occurred. (An exception occurred during a WebClient request.)
---> System.Net.WebException: An exception occurred during a WebClient request.
---> System.IO.IOException: Unable to read data from the transport connection: Connection reset by peer.
---> System.Net.Sockets.SocketException (104): Connection reset by peer
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.CreateException(SocketError error, Boolean forAsyncThrow)
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ReceiveAsync(Socket socket, CancellationToken cancellationToken)
at System.Net.Sockets.Socket.ReceiveAsync(Memory`1 buffer, SocketFlags socketFlags, Boolean fromNetworkStream, CancellationToken cancellationToken)
at System.Net.Sockets.NetworkStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
at System.Net.Security.SslStream.EnsureFullTlsFrameAsync[TIOAdapter](TIOAdapter adapter)
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
at System.Net.Security.SslStream.EnsureFullTlsFrameAsync[TIOAdapter](TIOAdapter adapter)
at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](TIOAdapter adapter, Memory`1 buffer)
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](TIOAdapter adapter, Memory`1 buffer)
at System.Net.Security.SslStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
at System.Net.Http.HttpConnection.ReadAsync(Memory`1 destination)
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
at System.Net.Http.HttpConnection.ReadAsync(Memory`1 destination)
at System.Net.Http.HttpConnection.ContentLengthReadStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
at System.Net.Http.HttpConnection.ContentLengthReadStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
at System.Net.WebClient.DownloadBitsAsync(WebRequest request, Stream writeStream, AsyncOperation asyncOp, Action`3 completionDelegate)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object s)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread threadPoolThread)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
at System.Threading.ThreadPool.<>c.<.cctor>b__86_0(Object state)
at System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore`1.SignalCompletion()
at Microsoft.Win32.SafeHandles.SafeFileHandle.ThreadPoolValueTaskSource.ExecuteInternal()
at Microsoft.Win32.SafeHandles.SafeFileHandle.ThreadPoolValueTaskSource.<>c.<System.Threading.IThreadPoolWorkItem.Execute>b__18_0(ThreadPoolValueTaskSource x)
at Microsoft.Win32.SafeHandles.SafeFileHandle.ThreadPoolValueTaskSource.System.Threading.IThreadPoolWorkItem.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
at System.Threading.Thread.StartCallback()
--- End of stack trace from previous location ---
--- End of inner exception stack trace ---
at System.Net.Security.SslStream.EnsureFullTlsFrameAsync[TIOAdapter](TIOAdapter adapter)
at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](TIOAdapter adapter, Memory`1 buffer)
at System.Net.Http.HttpConnection.ReadAsync(Memory`1 destination)
at System.Net.Http.HttpConnection.ContentLengthReadStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
at System.Net.WebClient.DownloadBitsAsync(WebRequest request, Stream writeStream, AsyncOperation asyncOp, Action`3 completionDelegate)
--- End of inner exception stack trace ---
at PuppeteerSharp.BrowserFetcher.DownloadAsync(String revision) in C:\projects\puppeteer-sharp\lib\PuppeteerSharp\BrowserFetcher.cs:line 298
at PuppeteerSharp.BrowserFetcher.DownloadAsync() in C:\projects\puppeteer-sharp\lib\PuppeteerSharp\BrowserFetcher.cs:line 265
--- End of inner exception stack trace ---
at Microsoft.FSharp.Control.AsyncResult`1.Commit() in D:\a\_work\1\s\src\fsharp\FSharp.Core\async.fs:line 391
at Microsoft.FSharp.Control.AsyncPrimitives.RunImmediate[a](CancellationToken cancellationToken, FSharpAsync`1 computation) in D:\a\_work\1\s\src\fsharp\FSharp.Core\async.fs:line 1063
at Microsoft.FSharp.Control.AsyncPrimitives.RunSynchronously[T](CancellationToken cancellationToken, FSharpAsync`1 computation, FSharpOption`1 timeout) in D:\a\_work\1\s\src\fsharp\FSharp.Core\async.fs:line 1069
at Microsoft.FSharp.Control.FSharpAsync.RunSynchronously[T](FSharpAsync`1 computation, FSharpOption`1 timeout, FSharpOption`1 cancellationToken) in D:\a\_work\1\s\src\fsharp\FSharp.Core\async.fs:line 1365
at ClientReportConclusionDrawer.Graph.Services.GraphService.<>c__DisplayClass2_0.<GenerateGaugeGraph>b__0() in /builds/src/ClientReportConclusionDrawer.Graph/Services/GraphService.cs:line 32
at System.Threading.Tasks.Task`1.InnerInvoke()
at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj)
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
at ClientReportConclusionDrawer.Graph.Services.GraphService.GenerateGaugeGraph(Double score, Int32 width, Int32 height, Int32 dpi, Int32 margin, Tuple`2 range, SupportedImageTypes imageType) in /builds/src/ClientReportConclusionDrawer.Graph/Services/GraphService.cs:line 27
I am running these integration tests using mcr.microsoft.com/dotnet/sdk:6.0-alpine3.14 base image. So maybe Alpine is to bare bones and I just miss dependencies. Searching on the internet about puppeteer-sharp and alpine I came across that it could be that you need to run puppeteer headless and in sandbox mode. So maybe adding the option to change the LaunchOptions could fix this problem.
Repro steps
-
To get the first error I made an simple REST API in C# calling a Plotly.NET F# script to generate a gauge graph I made. After that I just return: Chart.toSVGString and give that back to the user, trough the REST call. I used the mcr.microsoft.com/dotnet/sdk:6.0-alpine3.14 docker image and ran the intergration tests on gitlab.
-
The Docker image I used to get the second error:
FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine3.14
RUN apk add libgdiplus --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing/ --allow-untrusted
RUN apk add --no-cache \
chromium \
nss \
freetype \
harfbuzz \
ca-certificates \
ttf-freefont \
nodejs \
yarn
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
RUN yarn add puppeteer@10.0.0
RUN addgroup -S pptruser && adduser -S -g pptruser pptruser \
&& mkdir -p /home/pptruser/Downloads /app \
&& chown -R pptruser:pptruser /home/pptruser \
&& chown -R pptruser:pptruser /app
USER pptruser
Expected behavior
Locally I can run my integration tests and they all work. Running them on a Linux gitlab runner seems to break them. I expect the same result as when I run my tests on my Windows machine.
Actual behavior
The gitlab pipeline breaks when runinning the first two integration tests.
Known workarounds
Using the custom Dockerfile (that I published: https://hub.docker.com/repository/docker/whyellowmd/dotnet-puppeteer) seems to change the error but did not fix it.
Related information
- Alpine 3.14
- Plotly.NET 2.0.0-preview.16
Description
When doing integration tests with a dotnet sdk alpine image, I get the error that it can't find the chrome-linux directory.
When using a custom Docker image installing pupeteer on it, I get a different error saying something about an unhandled exception:
I am running these integration tests using mcr.microsoft.com/dotnet/sdk:6.0-alpine3.14 base image. So maybe Alpine is to bare bones and I just miss dependencies. Searching on the internet about puppeteer-sharp and alpine I came across that it could be that you need to run puppeteer headless and in sandbox mode. So maybe adding the option to change the LaunchOptions could fix this problem.
Repro steps
To get the first error I made an simple REST API in C# calling a Plotly.NET F# script to generate a gauge graph I made. After that I just return: Chart.toSVGString and give that back to the user, trough the REST call. I used the mcr.microsoft.com/dotnet/sdk:6.0-alpine3.14 docker image and ran the intergration tests on gitlab.
The Docker image I used to get the second error:
Expected behavior
Locally I can run my integration tests and they all work. Running them on a Linux gitlab runner seems to break them. I expect the same result as when I run my tests on my Windows machine.
Actual behavior
The gitlab pipeline breaks when runinning the first two integration tests.
Known workarounds
Using the custom Dockerfile (that I published: https://hub.docker.com/repository/docker/whyellowmd/dotnet-puppeteer) seems to change the error but did not fix it.
Related information