Create temporary directory handler.

This commit is contained in:
Matt T. Proud 2013-03-26 18:02:58 +01:00
parent 567a998e63
commit b86b0ea41a
6 changed files with 136 additions and 99 deletions

View file

@ -17,8 +17,7 @@ import (
"fmt" "fmt"
"github.com/prometheus/prometheus/rules/ast" "github.com/prometheus/prometheus/rules/ast"
"github.com/prometheus/prometheus/storage/metric" "github.com/prometheus/prometheus/storage/metric"
"io/ioutil" "github.com/prometheus/prometheus/utility/test"
"os"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -213,19 +212,10 @@ func vectorComparisonString(expected []string, actual []string) string {
} }
func TestExpressions(t *testing.T) { func TestExpressions(t *testing.T) {
temporaryDirectory, err := ioutil.TempDir("", "rule_expression_tests") temporaryDirectory := test.NewTemporaryDirectory("rule_expression_tests", t)
if err != nil { defer temporaryDirectory.Close()
t.Errorf("Could not create temporary directory: %q\n", err) tieredStorage := metric.NewTieredStorage(5000, 5000, 100, time.Second*30, time.Second*1, time.Second*20, temporaryDirectory.Path())
return
}
tieredStorage := metric.NewTieredStorage(5000, 5000, 100, time.Second*30, time.Second*1, time.Second*20, temporaryDirectory)
go tieredStorage.Serve() go tieredStorage.Serve()
defer func() {
tieredStorage.Close()
if err = os.RemoveAll(temporaryDirectory); err != nil {
t.Errorf("Could not remove temporary directory: %q\n", err)
}
}()
ast.SetStorage(tieredStorage) ast.SetStorage(tieredStorage)

View file

@ -16,13 +16,11 @@ package metric
import ( import (
"github.com/prometheus/prometheus/model" "github.com/prometheus/prometheus/model"
"github.com/prometheus/prometheus/utility/test" "github.com/prometheus/prometheus/utility/test"
"io"
"io/ioutil"
"testing" "testing"
"time" "time"
) )
func GetValueAtTimeTests(persistenceMaker func() (MetricPersistence, io.Closer), t test.Tester) { func GetValueAtTimeTests(persistenceMaker func() (MetricPersistence, test.Closer), t test.Tester) {
type value struct { type value struct {
year int year int
month time.Month month time.Month
@ -555,15 +553,11 @@ func GetValueAtTimeTests(persistenceMaker func() (MetricPersistence, io.Closer),
p, closer := persistenceMaker() p, closer := persistenceMaker()
defer func() { defer func() {
defer closer.Close()
err := p.Close() err := p.Close()
if err != nil { if err != nil {
t.Fatalf("Encountered anomaly closing persistence: %q\n", err) t.Fatalf("Encountered anomaly closing persistence: %q\n", err)
} }
err = closer.Close()
if err != nil {
t.Fatalf("Encountered anomaly purging persistence: %q\n", err)
}
}() }()
m := model.Metric{ m := model.Metric{
@ -609,7 +603,7 @@ func GetValueAtTimeTests(persistenceMaker func() (MetricPersistence, io.Closer),
} }
} }
func GetBoundaryValuesTests(persistenceMaker func() (MetricPersistence, io.Closer), t test.Tester) { func GetBoundaryValuesTests(persistenceMaker func() (MetricPersistence, test.Closer), t test.Tester) {
type value struct { type value struct {
year int year int
month time.Month month time.Month
@ -1001,14 +995,11 @@ func GetBoundaryValuesTests(persistenceMaker func() (MetricPersistence, io.Close
p, closer := persistenceMaker() p, closer := persistenceMaker()
defer func() { defer func() {
defer closer.Close()
err := p.Close() err := p.Close()
if err != nil { if err != nil {
t.Fatalf("Encountered anomaly closing persistence: %q\n", err) t.Fatalf("Encountered anomaly closing persistence: %q\n", err)
} }
err = closer.Close()
if err != nil {
t.Fatalf("Encountered anomaly purging persistence: %q\n", err)
}
}() }()
m := model.Metric{ m := model.Metric{
@ -1067,7 +1058,7 @@ func GetBoundaryValuesTests(persistenceMaker func() (MetricPersistence, io.Close
} }
} }
func GetRangeValuesTests(persistenceMaker func() (MetricPersistence, io.Closer), t test.Tester) { func GetRangeValuesTests(persistenceMaker func() (MetricPersistence, test.Closer), t test.Tester) {
type value struct { type value struct {
year int year int
month time.Month month time.Month
@ -1358,14 +1349,11 @@ func GetRangeValuesTests(persistenceMaker func() (MetricPersistence, io.Closer),
p, closer := persistenceMaker() p, closer := persistenceMaker()
defer func() { defer func() {
defer closer.Close()
err := p.Close() err := p.Close()
if err != nil { if err != nil {
t.Fatalf("Encountered anomaly closing persistence: %q\n", err) t.Fatalf("Encountered anomaly closing persistence: %q\n", err)
} }
err = closer.Close()
if err != nil {
t.Fatalf("Encountered anomaly purging persistence: %q\n", err)
}
}() }()
m := model.Metric{ m := model.Metric{
@ -1487,8 +1475,8 @@ func BenchmarkLevelDBGetRangeValues(b *testing.B) {
} }
func testMemoryGetValueAtTime(t test.Tester) { func testMemoryGetValueAtTime(t test.Tester) {
persistenceMaker := func() (MetricPersistence, io.Closer) { persistenceMaker := func() (MetricPersistence, test.Closer) {
return NewMemorySeriesStorage(), ioutil.NopCloser(nil) return NewMemorySeriesStorage(), test.NilCloser
} }
GetValueAtTimeTests(persistenceMaker, t) GetValueAtTimeTests(persistenceMaker, t)
@ -1505,8 +1493,8 @@ func BenchmarkMemoryGetValueAtTime(b *testing.B) {
} }
func testMemoryGetBoundaryValues(t test.Tester) { func testMemoryGetBoundaryValues(t test.Tester) {
persistenceMaker := func() (MetricPersistence, io.Closer) { persistenceMaker := func() (MetricPersistence, test.Closer) {
return NewMemorySeriesStorage(), ioutil.NopCloser(nil) return NewMemorySeriesStorage(), test.NilCloser
} }
GetBoundaryValuesTests(persistenceMaker, t) GetBoundaryValuesTests(persistenceMaker, t)
@ -1523,8 +1511,8 @@ func BenchmarkMemoryGetBoundaryValues(b *testing.B) {
} }
func testMemoryGetRangeValues(t test.Tester) { func testMemoryGetRangeValues(t test.Tester) {
persistenceMaker := func() (MetricPersistence, io.Closer) { persistenceMaker := func() (MetricPersistence, test.Closer) {
return NewMemorySeriesStorage(), ioutil.NopCloser(nil) return NewMemorySeriesStorage(), test.NilCloser
} }
GetRangeValuesTests(persistenceMaker, t) GetRangeValuesTests(persistenceMaker, t)

View file

@ -17,7 +17,6 @@ import (
"fmt" "fmt"
"github.com/prometheus/prometheus/model" "github.com/prometheus/prometheus/model"
"github.com/prometheus/prometheus/utility/test" "github.com/prometheus/prometheus/utility/test"
"io/ioutil"
"math" "math"
"math/rand" "math/rand"
"testing" "testing"
@ -186,9 +185,10 @@ func AppendSampleAsPureSingleEntityAppendTests(p MetricPersistence, t test.Teste
} }
} }
func StochasticTests(persistenceMaker func() MetricPersistence, t test.Tester) { func StochasticTests(persistenceMaker func() (MetricPersistence, test.Closer), t test.Tester) {
stochastic := func(x int) (success bool) { stochastic := func(x int) (success bool) {
p := persistenceMaker() p, closer := persistenceMaker()
defer closer.Close()
defer func() { defer func() {
err := p.Close() err := p.Close()
if err != nil { if err != nil {
@ -497,18 +497,15 @@ func BenchmarkLevelDBAppendSampleAsPureSingleEntityAppend(b *testing.B) {
} }
func testLevelDBStochastic(t test.Tester) { func testLevelDBStochastic(t test.Tester) {
persistenceMaker := func() MetricPersistence { persistenceMaker := func() (MetricPersistence, test.Closer) {
temporaryDirectory, err := ioutil.TempDir("", "test_leveldb_stochastic") temporaryDirectory := test.NewTemporaryDirectory("test_leveldb_stochastic", t)
if err != nil {
t.Errorf("Could not create test directory: %q\n", err)
}
p, err := NewLevelDBMetricPersistence(temporaryDirectory) p, err := NewLevelDBMetricPersistence(temporaryDirectory.Path())
if err != nil { if err != nil {
t.Errorf("Could not start up LevelDB: %q\n", err) t.Errorf("Could not start up LevelDB: %q\n", err)
} }
return p return p, temporaryDirectory
} }
StochasticTests(persistenceMaker, t) StochasticTests(persistenceMaker, t)
@ -585,8 +582,8 @@ func BenchmarkMemoryAppendSampleAsPureSingleEntityAppend(b *testing.B) {
} }
func testMemoryStochastic(t test.Tester) { func testMemoryStochastic(t test.Tester) {
persistenceMaker := func() MetricPersistence { persistenceMaker := func() (MetricPersistence, test.Closer) {
return NewMemorySeriesStorage() return NewMemorySeriesStorage(), test.NilCloser
} }
StochasticTests(persistenceMaker, t) StochasticTests(persistenceMaker, t)

View file

@ -17,9 +17,6 @@ import (
"fmt" "fmt"
"github.com/prometheus/prometheus/model" "github.com/prometheus/prometheus/model"
"github.com/prometheus/prometheus/utility/test" "github.com/prometheus/prometheus/utility/test"
"io"
"io/ioutil"
"os"
"time" "time"
) )
@ -34,52 +31,25 @@ func testAppendSample(p MetricPersistence, s model.Sample, t test.Tester) {
} }
} }
type purger struct { func buildLevelDBTestPersistencesMaker(name string, t test.Tester) func() (MetricPersistence, test.Closer) {
path string return func() (MetricPersistence, test.Closer) {
} temporaryDirectory := test.NewTemporaryDirectory("get_value_at_time", t)
func (p purger) Close() error { p, err := NewLevelDBMetricPersistence(temporaryDirectory.Path())
return os.RemoveAll(p.path)
}
func buildLevelDBTestPersistencesMaker(name string, t test.Tester) func() (MetricPersistence, io.Closer) {
return func() (MetricPersistence, io.Closer) {
temporaryDirectory, err := ioutil.TempDir("", "get_value_at_time")
if err != nil {
t.Errorf("Could not create test directory: %q\n", err)
}
p, err := NewLevelDBMetricPersistence(temporaryDirectory)
if err != nil { if err != nil {
t.Errorf("Could not start up LevelDB: %q\n", err) t.Errorf("Could not start up LevelDB: %q\n", err)
} }
purger := purger{ return p, temporaryDirectory
path: temporaryDirectory,
}
return p, purger
} }
} }
func buildLevelDBTestPersistence(name string, f func(p MetricPersistence, t test.Tester)) func(t test.Tester) { func buildLevelDBTestPersistence(name string, f func(p MetricPersistence, t test.Tester)) func(t test.Tester) {
return func(t test.Tester) { return func(t test.Tester) {
temporaryDirectory, err := ioutil.TempDir("", fmt.Sprintf("test_leveldb_%s", name)) temporaryDirectory := test.NewTemporaryDirectory(fmt.Sprintf("test_leveldb_%s", name), t)
defer temporaryDirectory.Close()
if err != nil { p, err := NewLevelDBMetricPersistence(temporaryDirectory.Path())
t.Errorf("Could not create test directory: %q\n", err)
return
}
defer func() {
err := os.RemoveAll(temporaryDirectory)
if err != nil {
t.Errorf("Could not remove temporary directory: %q\n", err)
}
}()
p, err := NewLevelDBMetricPersistence(temporaryDirectory)
if err != nil { if err != nil {
t.Errorf("Could not create LevelDB Metric Persistence: %q\n", err) t.Errorf("Could not create LevelDB Metric Persistence: %q\n", err)
} }

View file

@ -17,26 +17,25 @@ import (
"fmt" "fmt"
"github.com/prometheus/prometheus/model" "github.com/prometheus/prometheus/model"
"github.com/prometheus/prometheus/utility/test" "github.com/prometheus/prometheus/utility/test"
"io/ioutil"
"os"
"sort" "sort"
"testing" "testing"
"time" "time"
) )
type testTieredStorageCloser struct { type testTieredStorageCloser struct {
storage Storage storage Storage
dirName string directory test.Closer
} }
func (t *testTieredStorageCloser) Close() { func (t testTieredStorageCloser) Close() {
t.storage.Close() t.storage.Close()
os.RemoveAll(t.dirName) t.directory.Close()
} }
func newTestTieredStorage(t test.Tester) (storage Storage, closer *testTieredStorageCloser) { func newTestTieredStorage(t test.Tester) (storage Storage, closer test.Closer) {
tempDir, _ := ioutil.TempDir("", "test_tiered_storage") var directory test.TemporaryDirectory
storage = NewTieredStorage(5000000, 2500, 1000, 5*time.Second, 15*time.Second, 0*time.Second, tempDir) directory = test.NewTemporaryDirectory("test_tiered_storage", t)
storage = NewTieredStorage(5000000, 2500, 1000, 5*time.Second, 15*time.Second, 0*time.Second, directory.Path())
if storage == nil { if storage == nil {
t.Fatalf("%d. storage == nil") t.Fatalf("%d. storage == nil")
@ -44,8 +43,8 @@ func newTestTieredStorage(t test.Tester) (storage Storage, closer *testTieredSto
go storage.Serve() go storage.Serve()
closer = &testTieredStorageCloser{ closer = &testTieredStorageCloser{
storage: storage, storage: storage,
dirName: tempDir, directory: directory,
} }
return return
} }

93
utility/test/directory.go Normal file
View file

@ -0,0 +1,93 @@
// Copyright 2013 Prometheus Team
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package test
import (
"io/ioutil"
"os"
)
const (
// The base directory used for test emissions, which instructs the operating
// system to use the default temporary directory as the base or TMPDIR
// environment variable.
defaultDirectory = ""
// A NO-OP Closer.
NilCloser = nilCloser(true)
)
type Closer interface {
// Close reaps the underlying directory and its children. The directory
// could be deleted by its users already.
Close()
}
type nilCloser bool
func (c nilCloser) Close() {
}
// TemporaryDirectory models a closeable path for transient POSIX disk
// activities.
type TemporaryDirectory interface {
Closer
// Path returns the underlying path for access.
Path() string
}
// temporaryDirectory is kept as a private type due to private fields and their
// interactions.
type temporaryDirectory struct {
path string
tester Tester
}
func (t temporaryDirectory) Close() {
err := os.RemoveAll(t.path)
if err != nil {
switch {
case os.IsNotExist(err):
return
default:
t.tester.Fatal(err)
}
}
}
func (t temporaryDirectory) Path() string {
return t.path
}
// NewTemporaryDirectory creates a new temporary directory for transient POSIX
// activities.
func NewTemporaryDirectory(name string, t Tester) (handler TemporaryDirectory) {
var (
directory string
err error
)
directory, err = ioutil.TempDir(defaultDirectory, name)
if err != nil {
t.Fatal(err)
}
handler = temporaryDirectory{
path: directory,
tester: t,
}
return
}