Add HW 3
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
package hw3test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/require"
|
||||
"io"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
// RequireFileContent requires that the contents of the file match the contents of the reader.
|
||||
func RequireFileContent(t *TC, workdir, p string, f *EnvFile) {
|
||||
fullpath := path.Join(workdir, p)
|
||||
file, err := os.Open(fullpath)
|
||||
require.NoError(t, err, "failed to open file %s, expected it exists on disk", p)
|
||||
defer file.Close()
|
||||
|
||||
stat, err := file.Stat()
|
||||
require.NoError(t, err, "failed to stat file %s", p)
|
||||
require.Equal(t, f.Size, stat.Size(), "file %s has wrong size", p)
|
||||
require.NoError(t, CompareFileContent(t, file, f), "file %s has wrong content", p)
|
||||
}
|
||||
|
||||
// CompareFileContent compares first f.Size bytes of the reader with generated content.
|
||||
func CompareFileContent(t *TC, r io.Reader, f *EnvFile) error {
|
||||
actual := make([]byte, 64*1024)
|
||||
expected := make([]byte, len(actual))
|
||||
var generator io.Reader
|
||||
if f.TextOnly {
|
||||
generator = f.Open()
|
||||
} else {
|
||||
generator = newComparisonReader(f.GenSeed)
|
||||
}
|
||||
for offset := int64(0); offset < f.Size; {
|
||||
count := int64(len(actual))
|
||||
if remaining := f.Size - offset; remaining < count {
|
||||
count = remaining
|
||||
}
|
||||
if _, err := io.ReadFull(r, actual[:count]); err != nil {
|
||||
return fmt.Errorf("unexpected file error at position %d: %w", offset, err)
|
||||
}
|
||||
if _, err := io.ReadFull(generator, expected[:count]); err != nil {
|
||||
return fmt.Errorf("unexpected generator error at position %d: %w", offset, err)
|
||||
}
|
||||
if !bytes.Equal(actual[:count], expected[:count]) {
|
||||
for i := int64(0); i < count; i++ {
|
||||
if actual[i] != expected[i] {
|
||||
return fmt.Errorf("position %d, expected byte %d, got %d", offset+i, expected[i], actual[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
offset += count
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// comparisonReader emits the same bytes as rand.New(source).Read, seven bytes
|
||||
// from each Int63 value. It fills complete seven-byte groups without the
|
||||
// per-byte branch in math/rand.Read. Request bodies still use EnvFile.Open.
|
||||
type comparisonReader struct {
|
||||
source rand.Source
|
||||
value uint64
|
||||
remaining uint8
|
||||
}
|
||||
|
||||
func newComparisonReader(seed int64) *comparisonReader {
|
||||
return &comparisonReader{source: rand.NewSource(seed)}
|
||||
}
|
||||
|
||||
func (r *comparisonReader) Read(p []byte) (int, error) {
|
||||
n := len(p)
|
||||
for len(p) > 0 && r.remaining > 0 {
|
||||
p[0] = byte(r.value)
|
||||
r.value >>= 8
|
||||
r.remaining--
|
||||
p = p[1:]
|
||||
}
|
||||
for len(p) >= 7 {
|
||||
value := uint64(r.source.Int63())
|
||||
p[0] = byte(value)
|
||||
p[1] = byte(value >> 8)
|
||||
p[2] = byte(value >> 16)
|
||||
p[3] = byte(value >> 24)
|
||||
p[4] = byte(value >> 32)
|
||||
p[5] = byte(value >> 40)
|
||||
p[6] = byte(value >> 48)
|
||||
p = p[7:]
|
||||
}
|
||||
if len(p) > 0 {
|
||||
r.value = uint64(r.source.Int63())
|
||||
r.remaining = 7
|
||||
for i := range p {
|
||||
p[i] = byte(r.value)
|
||||
r.value >>= 8
|
||||
r.remaining--
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// RequireDir ensures that the directory exists on disk.
|
||||
func RequireDir(t *TC, workdir string, p string, dir *EnvDir) {
|
||||
fullpath := path.Join(workdir, p)
|
||||
stat, err := os.Stat(fullpath)
|
||||
require.NoError(t, err, "failed to stat directory %s, expected it exists on disk", p)
|
||||
require.True(t, stat.IsDir(), "expected %s to be a directory", p)
|
||||
}
|
||||
|
||||
// RequireNotExists ensures that the file/directory does not exist on disk.
|
||||
func RequireNotExists(t *TC, workdir string, p string) {
|
||||
fullpath := path.Join(workdir, p)
|
||||
_, err := os.Stat(fullpath)
|
||||
require.True(t, os.IsNotExist(err), "expected %s to not exist on disk", p)
|
||||
}
|
||||
|
||||
// RequireExists ensures that the file/directory exists on disk.
|
||||
func RequireExists(t *TC, workdir string, p string) {
|
||||
fullpath := path.Join(workdir, p)
|
||||
_, err := os.Stat(fullpath)
|
||||
require.NoError(t, err, "failed to stat %s, expected it exists on disk", p)
|
||||
}
|
||||
Reference in New Issue
Block a user