diff --git a/go.mod b/go.mod index 2c5b1365..d323b5c0 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ require ( contrib.go.opencensus.io/exporter/prometheus v0.1.0 contrib.go.opencensus.io/exporter/stackdriver v0.13.4 github.com/Azure/azure-sdk-for-go v36.2.0+incompatible // indirect - github.com/Azure/go-autorest v13.3.0+incompatible // indirect + github.com/Azure/go-autorest v13.3.0+incompatible // indirect github.com/Azure/go-autorest/autorest/adal v0.8.0 // indirect github.com/Azure/go-autorest/autorest/to v0.3.0 // indirect github.com/Azure/go-autorest/autorest/validation v0.2.0 // indirect @@ -48,6 +48,7 @@ require ( github.com/samuel/go-zookeeper v0.0.0-20190801204459-3c104360edc8 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/testify v1.4.0 go.opencensus.io v0.22.4 golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1 // indirect golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 // indirect diff --git a/tail/tail.go b/tail/tail.go index 622d5c54..51ee561b 100644 --- a/tail/tail.go +++ b/tail/tail.go @@ -207,6 +207,9 @@ func (t *Tailer) Read(b []byte) (int, error) { } } +// openSegment finds a WAL segment with a name that parses to n. This +// way we do not need to know how wide the segment filename is (i.e., +// how many zeros to pad with). func openSegment(dir string, n int) (io.ReadCloser, error) { files, err := fileutil.ReadDir(dir) if err != nil { @@ -214,12 +217,9 @@ func openSegment(dir string, n int) (io.ReadCloser, error) { } for _, fn := range files { k, err := strconv.Atoi(fn) - if err != nil || k < n { + if err != nil || k != n { continue } - if k > n { - return nil, errors.Errorf("next segment %d too high, expected %d", n, k) - } return wal.OpenReadSegment(filepath.Join(dir, fn)) } return nil, tsdb.ErrNotFound diff --git a/tail/tail_test.go b/tail/tail_test.go index 08b741a1..c8c72e78 100644 --- a/tail/tail_test.go +++ b/tail/tail_test.go @@ -17,15 +17,44 @@ package tail import ( "bytes" "context" + "fmt" "io/ioutil" "math/rand" "os" + "path" "testing" "time" "github.com/prometheus/tsdb/wal" + "github.com/stretchr/testify/require" ) +func TestOpenSegment(t *testing.T) { + dir, err := ioutil.TempDir("", "test_open_segment") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + + require.NoError(t, ioutil.WriteFile(path.Join(dir, "000000000000000000000nonsense"), []byte("bad"), 0777)) + + for i := 0; i < 10; i++ { + require.NoError(t, ioutil.WriteFile(path.Join(dir, fmt.Sprint("000000000000000000000", i)), []byte(fmt.Sprint(i)), 0777)) + } + for i := 19; i >= 10; i-- { + require.NoError(t, ioutil.WriteFile(path.Join(dir, fmt.Sprint("000000000000000000000", i)), []byte(fmt.Sprint(i)), 0777)) + } + + for i := 0; i < 20; i++ { + rc, err := openSegment(dir, i) + require.NoError(t, err) + body, err := ioutil.ReadAll(rc) + require.NoError(t, err) + require.Equal(t, fmt.Sprint(i), string(body)) + require.NoError(t, rc.Close()) + } +} + func TestTailFuzz(t *testing.T) { dir, err := ioutil.TempDir("", "test_tail") if err != nil {