cake-build / cake

:cake: Cake (C# Make) is a cross platform build automation system.
https://cakebuild.net
MIT License
3.88k stars 726 forks source link

FakeFileSystem throws on linux, when it is created on a Windows FakeEnvironment #4322

Open nils-a opened 1 month ago

nils-a commented 1 month ago

Prerequisites

Cake runner

Cake .NET Tool

Cake version

4.0.0

Operating system

Linux

Operating system architecture

64-Bit

CI Server

No response

What are you seeing?

demo code

using Cake.Core;
using Cake.Core.IO;
using Cake.Testing;
using Xunit;

namespace test1;

public class Tests
{
    [Fact]
    public void T1()
    {
        var fixture = new MyFixture();

        Assert.True(fixture.FileSystem.GetDirectory(fixture.Environment.WorkingDirectory).Exists);
    }
}

public class MyFixture
{
    public ICakeEnvironment Environment { get; }
    public IFileSystem FileSystem { get; }

    public MyFixture()
    {
        Environment = FakeEnvironment.CreateWindowsEnvironment();
        FileSystem = new FakeFileSystem(Environment);
    }
}

error

System.ArgumentException: Working directory cannot be relative.

System.ArgumentException
Working directory cannot be relative.
   at Cake.Testing.FakeFileSystemTree..ctor(ICakeEnvironment environment)
   at Cake.Testing.FakeFileSystem..ctor(ICakeEnvironment environment)
   at test1.MyFixture..ctor() in /home/nils/dev/test1/Class1.cs:line 27
   at test1.Tests.T1() in /home/nils/dev/test1/Class1.cs:line 13
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

What is expected?

I expect no error to occur.

Steps to Reproduce

Output log

No response

nils-a commented 1 month ago

Cause of the problem:

When the FakeFileSystem is created, it creates a FakeFileSystemTree using the given ICakeEnvironment:

https://github.com/cake-build/cake/blob/06e82a78bb8bfa978bcf838100caf69f1157cbdd/src/Cake.Testing/FakeFileSystem.cs#L23

The FakeFileSystemTree checks whether environment.WorkingDirectory.IsRelative is true and if so, it throws the exception:

https://github.com/cake-build/cake/blob/06e82a78bb8bfa978bcf838100caf69f1157cbdd/src/Cake.Testing/FakeFileSystemTree.cs#L31-L34

Now, ICakeEnvironment.WorkingDirectory.IsRelative is defined as:

https://github.com/cake-build/cake/blob/06e82a78bb8bfa978bcf838100caf69f1157cbdd/src/Cake.Core/IO/Path.cs#L98

PathHelper.IsPathRooted relies on

https://github.com/cake-build/cake/blob/06e82a78bb8bfa978bcf838100caf69f1157cbdd/src/Cake.Core/IO/PathHelper.cs#L13

And EnvironmentHelper.GetPlatformFamily in turn checks, what the current system is. I.e. the system running the test, not the FakeEnvironment that was defined in the test.

Thus, the WorkingDirectory, which is defined in FakeEnvironment as

https://github.com/cake-build/cake/blob/06e82a78bb8bfa978bcf838100caf69f1157cbdd/src/Cake.Testing/FakeEnvironment.cs#L86

is checked for IsRooted on my linux system, and not on the FakeEnvironment.

On my linux system, C:/Working is not rooted. Thus, it is treated as relative, and the exception is thrown.