Re: [Mono-dev] System.Diagnostics.Process behaves differently in and outside of a NUnit test case

2015-10-15 Thread Ludovic Henry
Hi Dan,

As I am currently working on the Process class, I am getting a look at your
bug.

Does setting  StandardOutputEncoding = Console.OutputEncoding on the
ProcessStartInfo passed to Start fixes your issue? This is the behaviour on
.NET, so this is the behaviour that we are going to adopt (at least for bug
compatibility).

Thank you! :)

Ludovic

-- Forwarded message -
From: Dan Liew 
Date: Fri, 9 Oct 2015, 14:40
Subject: [Mono-dev] System.Diagnostics.Process behaves differently in and
outside of a NUnit test case
To: 


Hi,

This is an issue that I was bitten by a while ago but I didn't post
here because I managed to work around it but it looks like something
inside mono changed between 3.12 and 4.0.4 which my broke my
workaround.

The issue basically is I observed my code failing when called from an
NUnit test but when run from an executable it would work fine. The
code in question [1] calls out to an external process using
``System.Diagnostics.Process`` where the standard input is redirected.
When running from an NUnit test a UTF-8 BOM gets sent to the process's
standard input and when running from an executable the UTF-8 BOM does
not get sent.

I looked at this again and I've noticed two things

* In System.Diagnostics.Process.Start_noshell() the encoding for the
writable end of the pipe connected to the child process's standard
input is taken from ``Console.Out.Encoding``. Is this really a good
idea? Depending on this global value seems like a bad idea and could
introduce weird race conditions if the Console.Out encoding is changed
in some way (e.g. ``Console.OutputEncoding = new
System.Text.UTF8Encoding(false);`` seems to do this and this the new
workaround I ended up using)

* When running in an executable the value of
``Console.Out.Encoding.emitUTF8Identifier`` is false but when running
in an NUnit test the value of
Console.Out.Encoding.emitUTF8Identifier`` is true!
I'm not sure if this is Mono's or NUnit's fault but this seems very wrong
to me.

I've filled a bug at [2] and [3] but thought I'd post about it here
too as this issue seems partially tied to some of mono's internal
implementation details.

[1] https://bugzilla.xamarin.com/attachment.cgi?id=13247
[2] https://bugzilla.xamarin.com/show_bug.cgi?id=21374
[3] https://github.com/nunit/nunit/issues/881

Thanks,
Dan.
___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list
___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


Re: [Mono-dev] System.Diagnostics.Process behaves differently in and outside of a NUnit test case

2015-10-15 Thread Dan Liew
Hi Ludovic,

On 15 October 2015 at 12:47, Ludovic Henry  wrote:
> Hi Dan,
>
> As I am currently working on the Process class, I am getting a look at your
> bug.

Thanks for taking a look :)

>
> Does setting  StandardOutputEncoding = Console.OutputEncoding on the
> ProcessStartInfo passed to Start fixes your issue? This is the behaviour on
> .NET, so this is the behaviour that we are going to adopt (at least for bug
> compatibility).

For the version of mono I'm currently using (4.0.4) doing this doesn't work

```
StartInfo = new ProcessStartInfo(PathToSolverExecutable);
StartInfo.Arguments = solverArguments;
StartInfo.RedirectStandardInput = true; // Neccessary so we can send our query
StartInfo.RedirectStandardOutput = true; // Necessary so we can read the output
StartInfo.RedirectStandardError = true;
StartInfo.UseShellExecute = false; // C# docs say this is required

// This is a HACK
TheEncoding = new System.Text.UTF8Encoding(/*
encoderShouldEmitUTF8Identifier=*/ false);
StartInfo.StandardOutputEncoding = TheEncoding;
```

The standard input stream is still sending the UTF-8 BOM. But doing
this before creating the process
works.

```
Console.OutputEncoding = new System.Text.UTF8Encoding(/*
encoderShouldEmitUTF8Identifier=*/ false);
```

The only reason I knew to do this is because I looked at the
implementation of ``System.Diagnostics.Process`` on my system
and saw that this the encoding that is being used comes from
``Console.Out.Encoding`` and took a guess that if I modified
``Console.OutputEncoding`` the change "might" propagate to
``Console.Out.Encoding``. Here's the implementation code I
was looking at.

```
if (startInfo.RedirectStandardInput == true) {
MonoIO.Close (stdin_rd, out error);
process.input_stream = new StreamWriter (new MonoSyncFileStream
(stdin_wr, FileAccess.Write, true, 8192), Console.Out.Encoding);
process.input_stream.AutoFlush = true;
}
```

However I've noticed that the code in the master branch of mono is
different. At a glance it looks like it's using
``startInfo.StandardOutputEncoding``
if it's not null

```
if (startInfo.RedirectStandardOutput) {
MonoIO.Close (stdout_write, out error);
Encoding stdoutEncoding = startInfo.StandardOutputEncoding ??
Console.Out.Encoding;
process.output_stream = new StreamReader (new FileStream (new
SafeFileHandle (stdout_read, false), FileAccess.Read, 8192, false),
stdoutEncoding, true, 8192);
}
```

So it looks like a nicer workaround is now available (I've not tested
it though). It's a bit of a pain though as I can't rely on it in older
versions of mono which means I have to use my horrible hack anyway :(


Please note that the bug I filled about NUnit [1] has had a response.
It sounds like NUnit is deliberately changing the encoding
on standard output because they expect that it being redirected to a file.

[1] https://github.com/nunit/nunit/issues/881
___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


[Mono-dev] System.Diagnostics.Process behaves differently in and outside of a NUnit test case

2015-10-09 Thread Dan Liew
Hi,

This is an issue that I was bitten by a while ago but I didn't post
here because I managed to work around it but it looks like something
inside mono changed between 3.12 and 4.0.4 which my broke my
workaround.

The issue basically is I observed my code failing when called from an
NUnit test but when run from an executable it would work fine. The
code in question [1] calls out to an external process using
``System.Diagnostics.Process`` where the standard input is redirected.
When running from an NUnit test a UTF-8 BOM gets sent to the process's
standard input and when running from an executable the UTF-8 BOM does
not get sent.

I looked at this again and I've noticed two things

* In System.Diagnostics.Process.Start_noshell() the encoding for the
writable end of the pipe connected to the child process's standard
input is taken from ``Console.Out.Encoding``. Is this really a good
idea? Depending on this global value seems like a bad idea and could
introduce weird race conditions if the Console.Out encoding is changed
in some way (e.g. ``Console.OutputEncoding = new
System.Text.UTF8Encoding(false);`` seems to do this and this the new
workaround I ended up using)

* When running in an executable the value of
``Console.Out.Encoding.emitUTF8Identifier`` is false but when running
in an NUnit test the value of
Console.Out.Encoding.emitUTF8Identifier`` is true!
I'm not sure if this is Mono's or NUnit's fault but this seems very wrong to me.

I've filled a bug at [2] and [3] but thought I'd post about it here
too as this issue seems partially tied to some of mono's internal
implementation details.

[1] https://bugzilla.xamarin.com/attachment.cgi?id=13247
[2] https://bugzilla.xamarin.com/show_bug.cgi?id=21374
[3] https://github.com/nunit/nunit/issues/881

Thanks,
Dan.
___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list