afero icon indicating copy to clipboard operation
afero copied to clipboard

memfs vs osfs behavior differences

Open shadowspore opened this issue 1 year ago • 0 comments

I've noticed a behavior difference between memfs and real os filesystem. Related issue: https://github.com/spf13/afero/issues/152 Related commit: https://github.com/spf13/afero/commit/ec3a3111d1e1bdff38a61e09d5a5f5e974905611 It says that returning io.ErrUnexpectedEOF is "in line with how the OS File works". However, it seems that this is not true? ping @bep

Test case to reproduce (tested on linux 6.6.7 ext4):

package filebase

import (
	"os"
	"testing"

	"github.com/spf13/afero"
	"github.com/stretchr/testify/require"
)

func TestAferoMemfs(t *testing.T) {
	memfs := afero.NewMemMapFs()
	osfs := afero.NewOsFs()

	// Create files.
	fmem, err := memfs.OpenFile("/tmp/foo.txt", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0o600)
	require.NoError(t, err)

	freal, err := osfs.OpenFile("/tmp/foo.txt", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0o600)
	require.NoError(t, err)

	// Write data and close files.
	{
		_, err = fmem.WriteString("abc")
		require.NoError(t, err)

		_, err = freal.WriteString("abc")
		require.NoError(t, err)

		require.NoError(t, fmem.Close())
		require.NoError(t, freal.Close())
	}

	// Open files again.
	fmem, err = memfs.OpenFile("/tmp/foo.txt", os.O_RDWR, 0o600)
	require.NoError(t, err)

	freal, err = osfs.OpenFile("/tmp/foo.txt", os.O_RDWR, 0o600)
	require.NoError(t, err)

	// Read data and truncate.
	{
		bufMem := make([]byte, 5)
		nMem, errMem := fmem.Read(bufMem)

		bufReal := make([]byte, 5)
		nReal, errReal := freal.Read(bufReal)

		require.Equal(t, errMem, errReal)
		require.Equal(t, nMem, nReal)
		require.Equal(t, bufMem, bufReal)

		require.NoError(t, fmem.Truncate(0))
		require.NoError(t, freal.Truncate(0))
	}

	// Try to read data again.
	{
		bufMem := make([]byte, 5)
		nMem, errMem := fmem.Read(bufMem)

		bufReal := make([]byte, 5)
		nReal, errReal := freal.Read(bufReal)

		require.Equal(t, errMem, errReal) // <- UnexpectedEOF vs EOF
		require.Equal(t, nMem, nReal)
		require.Equal(t, bufMem, bufReal)
	}
}

shadowspore avatar Dec 24 '23 09:12 shadowspore