mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-05 03:27:48 +00:00
a29e1d43f1
This replaces an earlier kludge which was at the wrong level and caused "GOARCH=386 tinygo test os" to fail to compile on linux. Stubbing just the one missing function, syscall.seek, lets os tests compile on linux 386, and skipping tests of seek and Fstat (which has a cryptic dependency on syscall.Seek via time) lets os tests pass on linux 386. The stub can be removed once tinygo implements go assembly and picks up the real definition.
252 lines
5.7 KiB
Go
252 lines
5.7 KiB
Go
// Copyright 2009 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package os_test
|
|
|
|
import (
|
|
"io"
|
|
"io/ioutil"
|
|
. "os"
|
|
"runtime"
|
|
"strings"
|
|
"syscall"
|
|
"testing"
|
|
)
|
|
|
|
// localTmp returns a local temporary directory not on NFS.
|
|
func localTmp() string {
|
|
return TempDir()
|
|
}
|
|
|
|
func newFile(testName string, t *testing.T) (f *File) {
|
|
f, err := CreateTemp("", testName)
|
|
if err != nil {
|
|
t.Fatalf("newFile %s: CreateTemp fails with %s", testName, err)
|
|
}
|
|
return
|
|
}
|
|
|
|
// Read with length 0 should not return EOF.
|
|
func TestRead0(t *testing.T) {
|
|
f := newFile("TestRead0", t)
|
|
defer Remove(f.Name())
|
|
defer f.Close()
|
|
|
|
const data = "hello, world\n"
|
|
io.WriteString(f, data)
|
|
f.Close()
|
|
f, err := Open(f.Name())
|
|
if err != nil {
|
|
t.Errorf("failed to reopen")
|
|
}
|
|
|
|
b := make([]byte, 0)
|
|
n, err := f.Read(b)
|
|
if n != 0 || err != nil {
|
|
t.Errorf("Read(0) = %d, %v, want 0, nil", n, err)
|
|
}
|
|
b = make([]byte, 5)
|
|
n, err = f.Read(b)
|
|
if n <= 0 || err != nil {
|
|
t.Errorf("Read(5) = %d, %v, want >0, nil", n, err)
|
|
}
|
|
}
|
|
|
|
// ReadAt with length 0 should not return EOF.
|
|
func TestReadAt0(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Log("TODO: implement Pread for Windows")
|
|
return
|
|
}
|
|
f := newFile("TestReadAt0", t)
|
|
defer Remove(f.Name())
|
|
defer f.Close()
|
|
|
|
const data = "hello, world\n"
|
|
io.WriteString(f, data)
|
|
|
|
b := make([]byte, 0)
|
|
n, err := f.ReadAt(b, 0)
|
|
if n != 0 || err != nil {
|
|
t.Errorf("ReadAt(0,0) = %d, %v, want 0, nil", n, err)
|
|
}
|
|
b = make([]byte, 5)
|
|
n, err = f.ReadAt(b, 0)
|
|
if n <= 0 || err != nil {
|
|
t.Errorf("ReadAt(5,0) = %d, %v, want >0, nil", n, err)
|
|
}
|
|
}
|
|
|
|
func checkMode(t *testing.T, path string, mode FileMode) {
|
|
dir, err := Stat(path)
|
|
if err != nil {
|
|
t.Fatalf("Stat %q (looking for mode %#o): %s", path, mode, err)
|
|
}
|
|
if dir.Mode()&ModePerm != mode {
|
|
t.Errorf("Stat %q: mode %#o want %#o", path, dir.Mode(), mode)
|
|
}
|
|
}
|
|
|
|
func TestSeek(t *testing.T) {
|
|
if runtime.GOARCH == "386" || runtime.GOARCH == "arm" {
|
|
t.Log("TODO: implement seek for 386 and arm")
|
|
return
|
|
}
|
|
f := newFile("TestSeek", t)
|
|
if f == nil {
|
|
t.Fatalf("f is nil")
|
|
return // TODO: remove
|
|
}
|
|
defer Remove(f.Name())
|
|
defer f.Close()
|
|
|
|
const data = "hello, world\n"
|
|
io.WriteString(f, data)
|
|
|
|
type test struct {
|
|
in int64
|
|
whence int
|
|
out int64
|
|
}
|
|
var tests = []test{
|
|
{0, io.SeekCurrent, int64(len(data))},
|
|
{0, io.SeekStart, 0},
|
|
{5, io.SeekStart, 5},
|
|
{0, io.SeekEnd, int64(len(data))},
|
|
{0, io.SeekStart, 0},
|
|
{-1, io.SeekEnd, int64(len(data)) - 1},
|
|
{1 << 33, io.SeekStart, 1 << 33},
|
|
{1 << 33, io.SeekEnd, 1<<33 + int64(len(data))},
|
|
|
|
// Issue 21681, Windows 4G-1, etc:
|
|
{1<<32 - 1, io.SeekStart, 1<<32 - 1},
|
|
{0, io.SeekCurrent, 1<<32 - 1},
|
|
{2<<32 - 1, io.SeekStart, 2<<32 - 1},
|
|
{0, io.SeekCurrent, 2<<32 - 1},
|
|
}
|
|
for i, tt := range tests {
|
|
off, err := f.Seek(tt.in, tt.whence)
|
|
if off != tt.out || err != nil {
|
|
if e, ok := err.(*PathError); ok && e.Err == syscall.EINVAL && tt.out > 1<<32 && runtime.GOOS == "linux" {
|
|
mounts, _ := ioutil.ReadFile("/proc/mounts")
|
|
if strings.Contains(string(mounts), "reiserfs") {
|
|
// Reiserfs rejects the big seeks.
|
|
t.Skipf("skipping test known to fail on reiserfs; https://golang.org/issue/91")
|
|
}
|
|
}
|
|
t.Errorf("#%d: Seek(%v, %v) = %v, %v want %v, nil", i, tt.in, tt.whence, off, err, tt.out)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestReadAt(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Log("TODO: implement Pread for Windows")
|
|
return
|
|
}
|
|
f := newFile("TestReadAt", t)
|
|
defer Remove(f.Name())
|
|
defer f.Close()
|
|
|
|
const data = "hello, world\n"
|
|
io.WriteString(f, data)
|
|
|
|
b := make([]byte, 5)
|
|
n, err := f.ReadAt(b, 7)
|
|
if err != nil || n != len(b) {
|
|
t.Fatalf("ReadAt 7: %d, %v", n, err)
|
|
}
|
|
if string(b) != "world" {
|
|
t.Fatalf("ReadAt 7: have %q want %q", string(b), "world")
|
|
}
|
|
}
|
|
|
|
// Verify that ReadAt doesn't affect seek offset.
|
|
// In the Plan 9 kernel, there used to be a bug in the implementation of
|
|
// the pread syscall, where the channel offset was erroneously updated after
|
|
// calling pread on a file.
|
|
func TestReadAtOffset(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Log("TODO: implement Pread for Windows")
|
|
return
|
|
}
|
|
f := newFile("TestReadAtOffset", t)
|
|
defer Remove(f.Name())
|
|
defer f.Close()
|
|
|
|
const data = "hello, world\n"
|
|
io.WriteString(f, data)
|
|
f.Close()
|
|
f, err := Open(f.Name())
|
|
if err != nil {
|
|
t.Errorf("failed to reopen")
|
|
}
|
|
|
|
b := make([]byte, 5)
|
|
|
|
n, err := f.ReadAt(b, 7)
|
|
if err != nil || n != len(b) {
|
|
t.Fatalf("ReadAt 7: %d, %v", n, err)
|
|
}
|
|
if string(b) != "world" {
|
|
t.Fatalf("ReadAt 7: have %q want %q", string(b), "world")
|
|
}
|
|
|
|
n, err = f.Read(b)
|
|
if err != nil || n != len(b) {
|
|
t.Fatalf("Read: %d, %v", n, err)
|
|
}
|
|
if string(b) != "hello" {
|
|
t.Fatalf("Read: have %q want %q", string(b), "hello")
|
|
}
|
|
}
|
|
|
|
// Verify that ReadAt doesn't allow negative offset.
|
|
func TestReadAtNegativeOffset(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Log("TODO: implement Pread for Windows")
|
|
return
|
|
}
|
|
f := newFile("TestReadAtNegativeOffset", t)
|
|
defer Remove(f.Name())
|
|
defer f.Close()
|
|
|
|
const data = "hello, world\n"
|
|
io.WriteString(f, data)
|
|
f.Close()
|
|
f, err := Open(f.Name())
|
|
if err != nil {
|
|
t.Errorf("failed to reopen")
|
|
}
|
|
|
|
b := make([]byte, 5)
|
|
|
|
n, err := f.ReadAt(b, -10)
|
|
|
|
const wantsub = "negative offset"
|
|
if !strings.Contains(err.Error(), wantsub) || n != 0 {
|
|
t.Errorf("ReadAt(-10) = %v, %v; want 0, ...%q...", n, err, wantsub)
|
|
}
|
|
}
|
|
|
|
func TestReadAtEOF(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Log("TODO: implement Pread for Windows")
|
|
return
|
|
}
|
|
f := newFile("TestReadAtEOF", t)
|
|
defer Remove(f.Name())
|
|
defer f.Close()
|
|
|
|
_, err := f.ReadAt(make([]byte, 10), 0)
|
|
switch err {
|
|
case io.EOF:
|
|
// all good
|
|
case nil:
|
|
t.Fatalf("ReadAt succeeded")
|
|
default:
|
|
t.Fatalf("ReadAt failed: %s", err)
|
|
}
|
|
}
|