Unverified Commit 01ce5da4 authored by Steven Allen's avatar Steven Allen Committed by GitHub

Merge pull request #73 from ipfs/fix/skip-non-directories

Windows CI + Fixes
parents 8a9ada91 e20a965e
version: 2.1 version: 2.1
orbs: orbs:
ci-go: ipfs/ci-go@0.2.1 ci-go: ipfs/ci-go@0.2.1
win: circleci/windows@2.4.0
jobs:
"windows-test":
executor: win/default
steps:
- checkout
- run:
name: "Go test"
command: go test .
workflows: workflows:
version: 2 version: 2
...@@ -9,3 +19,4 @@ workflows: ...@@ -9,3 +19,4 @@ workflows:
- ci-go/build - ci-go/build
- ci-go/lint - ci-go/lint
- ci-go/test - ci-go/test
- windows-test
...@@ -7,11 +7,12 @@ import ( ...@@ -7,11 +7,12 @@ import (
"math/rand" "math/rand"
"os" "os"
"path/filepath" "path/filepath"
"runtime"
"testing" "testing"
"time" "time"
"github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore"
"github.com/ipfs/go-ds-flatfs" flatfs "github.com/ipfs/go-ds-flatfs"
) )
func TestMove(t *testing.T) { func TestMove(t *testing.T) {
...@@ -57,6 +58,9 @@ func TestMove(t *testing.T) { ...@@ -57,6 +58,9 @@ func TestMove(t *testing.T) {
} }
func TestMoveRestart(t *testing.T) { func TestMoveRestart(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip()
}
tempdir, cleanup := tempdir(t) tempdir, cleanup := tempdir(t)
defer cleanup() defer cleanup()
......
...@@ -7,7 +7,6 @@ import ( ...@@ -7,7 +7,6 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io/ioutil"
"math" "math"
"math/rand" "math/rand"
"os" "os"
...@@ -241,12 +240,12 @@ func Open(path string, syncFiles bool) (*Datastore, error) { ...@@ -241,12 +240,12 @@ func Open(path string, syncFiles bool) (*Datastore, error) {
tempPath := filepath.Join(path, ".temp") tempPath := filepath.Join(path, ".temp")
err = os.RemoveAll(tempPath) err = os.RemoveAll(tempPath)
if err != nil && !os.IsNotExist(err) { if err != nil && !os.IsNotExist(err) {
return nil, fmt.Errorf("failed to remove temporary directory: %w", err) return nil, fmt.Errorf("failed to remove temporary directory: %v", err)
} }
err = os.Mkdir(tempPath, 0755) err = os.Mkdir(tempPath, 0755)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create temporary directory: %w", err) return nil, fmt.Errorf("failed to create temporary directory: %v", err)
} }
shardId, err := ReadShardFunc(path) shardId, err := ReadShardFunc(path)
...@@ -380,7 +379,7 @@ var putMaxRetries = 6 ...@@ -380,7 +379,7 @@ var putMaxRetries = 6
// will win. // will win.
func (fs *Datastore) Put(key datastore.Key, value []byte) error { func (fs *Datastore) Put(key datastore.Key, value []byte) error {
if !keyIsValid(key) { if !keyIsValid(key) {
return fmt.Errorf("when putting '%q': %w", key, ErrInvalidKey) return fmt.Errorf("when putting '%q': %v", key, ErrInvalidKey)
} }
fs.shutdownLock.RLock() fs.shutdownLock.RLock()
...@@ -608,7 +607,7 @@ func (fs *Datastore) Get(key datastore.Key) (value []byte, err error) { ...@@ -608,7 +607,7 @@ func (fs *Datastore) Get(key datastore.Key) (value []byte, err error) {
} }
_, path := fs.encode(key) _, path := fs.encode(key)
data, err := ioutil.ReadFile(path) data, err := readFile(path)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil, datastore.ErrNotFound return nil, datastore.ErrNotFound
...@@ -734,11 +733,15 @@ func (fs *Datastore) walkTopLevel(path string, result *query.ResultBuilder) erro ...@@ -734,11 +733,15 @@ func (fs *Datastore) walkTopLevel(path string, result *query.ResultBuilder) erro
return err return err
} }
defer dir.Close() defer dir.Close()
names, err := dir.Readdirnames(-1) entries, err := dir.Readdir(-1)
if err != nil { if err != nil {
return err return err
} }
for _, dir := range names { for _, entry := range entries {
if !entry.IsDir() {
continue
}
dir := entry.Name()
if len(dir) == 0 || dir[0] == '.' { if len(dir) == 0 || dir[0] == '.' {
continue continue
} }
...@@ -1019,7 +1022,7 @@ func (fs *Datastore) writeDiskUsageFile(du int64, doSync bool) { ...@@ -1019,7 +1022,7 @@ func (fs *Datastore) writeDiskUsageFile(du int64, doSync bool) {
// readDiskUsageFile is only safe to call in Open() // readDiskUsageFile is only safe to call in Open()
func (fs *Datastore) readDiskUsageFile() int64 { func (fs *Datastore) readDiskUsageFile() int64 {
fpath := filepath.Join(fs.path, DiskUsageFile) fpath := filepath.Join(fs.path, DiskUsageFile)
duB, err := ioutil.ReadFile(fpath) duB, err := readFile(fpath)
if err != nil { if err != nil {
return 0 return 0
} }
...@@ -1056,10 +1059,11 @@ func (fs *Datastore) Accuracy() string { ...@@ -1056,10 +1059,11 @@ func (fs *Datastore) Accuracy() string {
} }
func (fs *Datastore) tempFile() (*os.File, error) { func (fs *Datastore) tempFile() (*os.File, error) {
file, err := ioutil.TempFile(fs.tempPath, "temp-") file, err := tempFile(fs.tempPath, "temp-")
return file, err return file, err
} }
// only call this on directories.
func (fs *Datastore) walk(path string, qrb *query.ResultBuilder) error { func (fs *Datastore) walk(path string, qrb *query.ResultBuilder) error {
dir, err := os.Open(path) dir, err := os.Open(path)
if err != nil { if err != nil {
...@@ -1071,15 +1075,6 @@ func (fs *Datastore) walk(path string, qrb *query.ResultBuilder) error { ...@@ -1071,15 +1075,6 @@ func (fs *Datastore) walk(path string, qrb *query.ResultBuilder) error {
} }
defer dir.Close() defer dir.Close()
// ignore non-directories
fileInfo, err := dir.Stat()
if err != nil {
return err
}
if !fileInfo.IsDir() {
return nil
}
names, err := dir.Readdirnames(-1) names, err := dir.Readdirnames(-1)
if err != nil { if err != nil {
return err return err
...@@ -1099,7 +1094,7 @@ func (fs *Datastore) walk(path string, qrb *query.ResultBuilder) error { ...@@ -1099,7 +1094,7 @@ func (fs *Datastore) walk(path string, qrb *query.ResultBuilder) error {
var result query.Result var result query.Result
result.Key = key.String() result.Key = key.String()
if !qrb.Query.KeysOnly { if !qrb.Query.KeysOnly {
value, err := ioutil.ReadFile(filepath.Join(path, fn)) value, err := readFile(filepath.Join(path, fn))
if err != nil { if err != nil {
result.Error = err result.Error = err
} else { } else {
...@@ -1163,7 +1158,7 @@ func (fs *Datastore) Batch() (datastore.Batch, error) { ...@@ -1163,7 +1158,7 @@ func (fs *Datastore) Batch() (datastore.Batch, error) {
func (bt *flatfsBatch) Put(key datastore.Key, val []byte) error { func (bt *flatfsBatch) Put(key datastore.Key, val []byte) error {
if !keyIsValid(key) { if !keyIsValid(key) {
return fmt.Errorf("when putting '%q': %w", key, ErrInvalidKey) return fmt.Errorf("when putting '%q': %v", key, ErrInvalidKey)
} }
bt.puts[key] = val bt.puts[key] = val
return nil return nil
......
// +build !windows
package flatfs
import (
"io/ioutil"
"os"
)
func tempFile(dir, pattern string) (*os.File, error) {
return ioutil.TempFile(dir, pattern)
}
func readFile(filename string) ([]byte, error) {
return ioutil.ReadFile(filename)
}
// +build windows
// Copyright 2010 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.
// Note: This file is a variant of a subset of the golang standard library
// src/io/ioutil/tempfile.go
// with calls to os.Open replaced with the goissue34681.Open variant.
package flatfs
import (
"bytes"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
"time"
goissue34681 "github.com/alexbrainman/goissue34681"
)
var tmpRand uint32
var randmu sync.Mutex
func reseed() uint32 {
return uint32(time.Now().UnixNano() + int64(os.Getpid()))
}
func nextRandom() string {
randmu.Lock()
r := tmpRand
if r == 0 {
r = reseed()
}
r = r*1664525 + 1013904223 // constants from Numerical Recipes
tmpRand = r
randmu.Unlock()
return strconv.Itoa(int(1e9 + r%1e9))[1:]
}
func prefixAndSuffix(pattern string) (prefix, suffix string) {
if pos := strings.LastIndex(pattern, "*"); pos != -1 {
prefix, suffix = pattern[:pos], pattern[pos+1:]
} else {
prefix = pattern
}
return
}
func tempFile(dir, pattern string) (f *os.File, err error) {
if dir == "" {
dir = os.TempDir()
}
prefix, suffix := prefixAndSuffix(pattern)
nconflict := 0
for i := 0; i < 10000; i++ {
name := filepath.Join(dir, prefix+nextRandom()+suffix)
f, err = goissue34681.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
if os.IsExist(err) {
if nconflict++; nconflict > 10 {
randmu.Lock()
tmpRand = reseed()
randmu.Unlock()
}
continue
}
break
}
return
}
func readFile(filename string) ([]byte, error) {
f, err := goissue34681.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
// It's a good but not certain bet that FileInfo will tell us exactly how much to
// read, so let's try it but be prepared for the answer to be wrong.
var n int64 = bytes.MinRead
if fi, err := f.Stat(); err == nil {
// As initial capacity for readAll, use Size + a little extra in case Size
// is zero, and to avoid another allocation after Read has filled the
// buffer. The readAll call will read into its allocated internal buffer
// cheaply. If the size was wrong, we'll either waste some space off the end
// or reallocate as needed, but in the overwhelmingly common case we'll get
// it just right.
if size := fi.Size() + bytes.MinRead; size > n {
n = size
}
}
return ioutil.ReadAll(f)
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment