blob: 5e07789c007ff4fb612df3b30895794e49cb8e47 [file] [log] [blame]
// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package internal_test
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"reflect"
"strings"
"testing"
"time"
"v.io/x/ref/test"
"messenger/internal"
)
func TestFileStorage(t *testing.T) {
ctx, shutdown := test.V23Init()
defer shutdown()
tmpdir, err := ioutil.TempDir("", "TestFileStorage-")
if err != nil {
t.Fatalf("ioutil.TempDir failed: %v", err)
}
defer os.RemoveAll(tmpdir)
msgTxt := []byte("Hello World!")
msg := internal.NewMessageFromBytes(msgTxt)
fs := internal.NewFileStorage(ctx, tmpdir)
// Open, Write whole content, Close
w, err := fs.OpenWrite(ctx, msg, 0)
if err != nil {
t.Fatalf("fs.OpenWrite failed: %v", err)
}
if _, err := fs.OpenWrite(ctx, msg, 0); err == nil {
t.Errorf("Unexpected concurrent fs.OpenWrite success")
}
if _, err := w.Write(msgTxt); err != nil {
t.Fatalf("w.Write failed: %v", err)
}
if err := w.Close(); err != nil {
t.Fatalf("w.Close failed: %v", err)
}
// Re-opening the file for write failed after the file is complete.
if _, err := fs.OpenWrite(ctx, msg, 0); err == nil {
t.Errorf("Unexpected fs.OpenWrite success after complete write")
}
if _, err := fs.Offset(ctx, msg.Id); err == nil {
t.Errorf("Unexpected fs.Offset success after complete write")
}
// Open, Read whole content, Close
m, r, err := fs.OpenRead(ctx, msg.Id)
if err != nil {
t.Fatalf("fs.OpenRead failed: %v", err)
}
if !bytes.Equal(m.Hash(), msg.Hash()) {
t.Errorf("Unexpected message hash. Got %v, expected %v", m.Hash(), msg.Hash())
}
b, err := ioutil.ReadAll(r)
if err != nil {
t.Fatalf("ioutil.ReadAll failed: %v", err)
}
if !bytes.Equal(b, msgTxt) {
t.Errorf("Unexpected content. Got %v, expected %v", b, msgTxt)
}
pi := internal.PeerInfo{
Sent: false,
NumAttempts: 1,
NextAttempt: time.Now().UTC(),
}
if err := fs.SetPeerInfo(ctx, msg.Id, "foo", pi); err != nil {
t.Errorf("fs.SetPeerInfo failed: %v", err)
}
pi2 := fs.PeerInfo(ctx, msg.Id, "foo")
if !reflect.DeepEqual(pi, pi2) {
t.Errorf("Unexpected PeerInfo. Got %v, expected %v", pi2, pi)
}
}
func TestFileStorageResume(t *testing.T) {
ctx, shutdown := test.V23Init()
defer shutdown()
tmpdir, err := ioutil.TempDir("", "TestFileStorageResume-")
if err != nil {
t.Fatalf("ioutil.TempDir failed: %v", err)
}
defer os.RemoveAll(tmpdir)
msgTxt := []byte("Hello World\n")
msg := internal.NewMessageFromBytes(msgTxt)
fs := internal.NewFileStorage(ctx, tmpdir)
// Open, Write 5 bytes, Close
w, err := fs.OpenWrite(ctx, msg, 0)
if err != nil {
t.Fatalf("fs.OpenWrite failed: %v", err)
}
if _, err := w.Write(msgTxt[:5]); err != nil {
t.Fatalf("w.Write failed: %v", err)
}
if err := w.Close(); err != nil {
t.Fatalf("w.Close failed: %v", err)
}
if offset, err := fs.Offset(ctx, msg.Id); err != nil {
t.Errorf("fs.Offset failed: %v", err)
} else if expected := int64(5); offset != expected {
t.Errorf("unexpected offset. Got %d, expected %d", offset, expected)
}
// Open, Write remaining bytes, Close
if w, err = fs.OpenWrite(ctx, msg, 5); err != nil {
t.Fatalf("fs.OpenWrite failed: %v", err)
}
if _, err := w.Write(msgTxt[5:]); err != nil {
t.Fatalf("w.Write failed: %v", err)
}
if err := w.Close(); err != nil {
t.Fatalf("w.Close failed: %v", err)
}
if _, err := fs.OpenWrite(ctx, msg, 0); err == nil {
t.Errorf("Unexpected fs.OpenWrite success after complete write")
}
if _, err := fs.Offset(ctx, msg.Id); err == nil {
t.Errorf("Unexpected fs.Offset success after complete write")
}
// Open, Read 8 bytes, Close
_, r, err := fs.OpenRead(ctx, msg.Id)
if err != nil {
t.Fatalf("fs.OpenRead failed: %v", err)
}
b8 := make([]byte, 8)
if n, err := r.Read(b8); err != nil || n != 8 {
t.Errorf("Unexpected read. Got (%d, %v), expected (8, nil)", n, err)
}
if err := r.Close(); err != nil {
t.Fatalf("r.Close failed: %v", err)
}
// Open, Read remaining bytes, Close
if _, r, err = fs.OpenRead(ctx, msg.Id); err != nil {
t.Fatalf("fs.OpenRead failed: %v", err)
}
r.Seek(8, 0)
b, err := ioutil.ReadAll(r)
if err != nil {
t.Fatalf("ioutil.ReadAll failed: %v", err)
}
concat := append(b8, b...)
if !bytes.Equal(concat, msgTxt) {
t.Errorf("Unexpected content. Got %v, expected %v", concat, msgTxt)
}
}
func TestFileStorageManifest(t *testing.T) {
ctx, shutdown := test.V23Init()
defer shutdown()
tmpdir, err := ioutil.TempDir("", "TestFileStorageManifest-")
if err != nil {
t.Fatalf("ioutil.TempDir failed: %v", err)
}
defer os.RemoveAll(tmpdir)
fs := internal.NewFileStorage(ctx, tmpdir)
const N = 200
// Create N messages.
for i := 0; i < N; i++ {
name := fmt.Sprintf("file-%03d", i)
content := strings.Repeat(name, i)
msg := internal.NewMessageFromBytes([]byte(content))
msg.Id = name
msg.Lifespan = time.Hour
// Open, Write whole content, Close
w, err := fs.OpenWrite(ctx, msg, 0)
if err != nil {
t.Fatalf("fs.OpenWrite failed: %v", err)
}
if _, err := fs.OpenWrite(ctx, msg, 0); err == nil {
t.Errorf("Unexpected concurrent fs.OpenWrite success")
}
if _, err := w.Write([]byte(content)); err != nil {
t.Fatalf("w.Write failed: %v", err)
}
if err := w.Close(); err != nil {
t.Fatalf("w.Close failed: %v", err)
}
}
ch, err := fs.Manifest(ctx)
if err != nil {
t.Fatalf("fs.Manifest failed: %v", err)
}
count := 0
for range ch {
count++
}
if expected := N; count != expected {
t.Errorf("unexpected number of messages. Got %d, expected %d", count, expected)
}
}