mirror of
				https://github.com/prometheus/prometheus.git
				synced 2025-11-04 02:11:01 +01:00 
			
		
		
		
	See https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/modernize for details. This ran into a few issues (arguably bugs in the modernize tool), which I will fix in the next commit, so that we have transparency what was done automatically. Beyond those hiccups, I believe all the changes applied are legitimate. Even where there might be no tangible direct gain, I would argue it's still better to use the "modern" way to avoid micro discussions in tiny style PRs later. Signed-off-by: beorn7 <beorn@grafana.com>
		
			
				
	
	
		
			166 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			166 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2013 The Prometheus Authors
 | 
						|
// 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 testutil
 | 
						|
 | 
						|
import (
 | 
						|
	"crypto/sha256"
 | 
						|
	"io"
 | 
						|
	"os"
 | 
						|
	"path/filepath"
 | 
						|
	"strconv"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"github.com/stretchr/testify/require"
 | 
						|
)
 | 
						|
 | 
						|
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 = ""
 | 
						|
 | 
						|
	// NilCloser is a no-op Closer.
 | 
						|
	NilCloser = nilCloser(true)
 | 
						|
 | 
						|
	// The number of times that a TemporaryDirectory will retry its removal.
 | 
						|
	temporaryDirectoryRemoveRetries = 2
 | 
						|
)
 | 
						|
 | 
						|
type (
 | 
						|
	// Closer is the interface that wraps the Close method.
 | 
						|
	Closer interface {
 | 
						|
		// Close reaps the underlying directory and its children. The directory
 | 
						|
		// could be deleted by its users already.
 | 
						|
		Close()
 | 
						|
	}
 | 
						|
 | 
						|
	nilCloser bool
 | 
						|
 | 
						|
	// TemporaryDirectory models a closeable path for transient POSIX disk
 | 
						|
	// activities.
 | 
						|
	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.
 | 
						|
	temporaryDirectory struct {
 | 
						|
		path   string
 | 
						|
		tester T
 | 
						|
	}
 | 
						|
 | 
						|
	callbackCloser struct {
 | 
						|
		fn func()
 | 
						|
	}
 | 
						|
 | 
						|
	// T implements the needed methods of testing.TB so that we do not need
 | 
						|
	// to actually import testing (which has the side effect of adding all
 | 
						|
	// the test flags, which we do not want in non-test binaries even if
 | 
						|
	// they make use of these utilities for some reason).
 | 
						|
	T interface {
 | 
						|
		Errorf(format string, args ...any)
 | 
						|
		FailNow()
 | 
						|
	}
 | 
						|
)
 | 
						|
 | 
						|
func (nilCloser) Close() {
 | 
						|
}
 | 
						|
 | 
						|
func (c callbackCloser) Close() {
 | 
						|
	c.fn()
 | 
						|
}
 | 
						|
 | 
						|
// NewCallbackCloser returns a Closer that calls the provided function upon
 | 
						|
// closing.
 | 
						|
func NewCallbackCloser(fn func()) Closer {
 | 
						|
	return &callbackCloser{
 | 
						|
		fn: fn,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (t temporaryDirectory) Close() {
 | 
						|
	retries := temporaryDirectoryRemoveRetries
 | 
						|
	err := os.RemoveAll(t.path)
 | 
						|
	for err != nil && retries > 0 {
 | 
						|
		switch {
 | 
						|
		case os.IsNotExist(err):
 | 
						|
			err = nil
 | 
						|
		default:
 | 
						|
			retries--
 | 
						|
			err = os.RemoveAll(t.path)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	require.NoError(t.tester, err)
 | 
						|
}
 | 
						|
 | 
						|
func (t temporaryDirectory) Path() string {
 | 
						|
	return t.path
 | 
						|
}
 | 
						|
 | 
						|
// NewTemporaryDirectory creates a new temporary directory for transient POSIX
 | 
						|
// activities.
 | 
						|
func NewTemporaryDirectory(name string, t T) (handler TemporaryDirectory) {
 | 
						|
	var (
 | 
						|
		directory string
 | 
						|
		err       error
 | 
						|
	)
 | 
						|
 | 
						|
	directory, err = os.MkdirTemp(defaultDirectory, name)
 | 
						|
	require.NoError(t, err)
 | 
						|
 | 
						|
	handler = temporaryDirectory{
 | 
						|
		path:   directory,
 | 
						|
		tester: t,
 | 
						|
	}
 | 
						|
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
// DirHash returns a hash of all files attributes and their content within a directory.
 | 
						|
func DirHash(t *testing.T, path string) []byte {
 | 
						|
	hash := sha256.New()
 | 
						|
	err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
 | 
						|
		require.NoError(t, err)
 | 
						|
 | 
						|
		if info.IsDir() {
 | 
						|
			return nil
 | 
						|
		}
 | 
						|
		f, err := os.Open(path)
 | 
						|
		require.NoError(t, err)
 | 
						|
		defer f.Close()
 | 
						|
 | 
						|
		_, err = io.Copy(hash, f)
 | 
						|
		require.NoError(t, err)
 | 
						|
 | 
						|
		_, err = io.WriteString(hash, strconv.Itoa(int(info.Size())))
 | 
						|
		require.NoError(t, err)
 | 
						|
 | 
						|
		_, err = io.WriteString(hash, info.Name())
 | 
						|
		require.NoError(t, err)
 | 
						|
 | 
						|
		modTime, err := info.ModTime().GobEncode()
 | 
						|
		require.NoError(t, err)
 | 
						|
 | 
						|
		_, err = hash.Write(modTime)
 | 
						|
		require.NoError(t, err)
 | 
						|
		return nil
 | 
						|
	})
 | 
						|
	require.NoError(t, err)
 | 
						|
 | 
						|
	return hash.Sum(nil)
 | 
						|
}
 |