package jsondb_test
import (
"io/ioutil"
"os"
"path"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/osbuild/osbuild-composer/internal/jsondb"
)
type document struct {
Animal string `json:"animal"`
CanSwim bool `json:"can-swim"`
}
func cleanupTempDir(t *testing.T, dir string) {
err := os.RemoveAll(dir)
require.NoError(t, err)
}
// If the passed directory is not readable (writable), we should notice on the
// first read (write).
func TestDegenerate(t *testing.T) {
t.Run("no-exist", func(t *testing.T) {
db := jsondb.New("/non-existant-directory", 0755)
var d document
exist, err := db.Read("one", &d)
assert.False(t, exist)
assert.NoError(t, err)
err = db.Write("one", &d)
assert.Error(t, err)
l, err := db.List()
assert.Error(t, err)
assert.Nil(t, l)
})
t.Run("invalid-json", func(t *testing.T) {
dir, err := ioutil.TempDir("", "jsondb-test-")
require.NoError(t, err)
defer cleanupTempDir(t, dir)
db := jsondb.New(dir, 0755)
// write-only file
err = ioutil.WriteFile(path.Join(dir, "one.json"), []byte("{"), 0644)
require.NoError(t, err)
var d document
_, err = db.Read("one", &d)
assert.Error(t, err)
})
}
func TestCorrupt(t *testing.T) {
dir, err := ioutil.TempDir("", "jsondb-test-")
require.NoError(t, err)
defer cleanupTempDir(t, dir)
err = ioutil.WriteFile(path.Join(dir, "one.json"), []byte("{"), 0755)
require.NoError(t, err)
db := jsondb.New(dir, 0755)
var d document
_, err = db.Read("one", &d)
require.Error(t, err)
}
func TestRead(t *testing.T) {
dir, err := ioutil.TempDir("", "jsondb-test-")
require.NoError(t, err)
defer cleanupTempDir(t, dir)
err = ioutil.WriteFile(path.Join(dir, "one.json"), []byte("true"), 0755)
require.NoError(t, err)
db := jsondb.New(dir, 0755)
var b bool
exists, err := db.Read("one", &b)
require.NoError(t, err)
require.True(t, exists)
require.True(t, b)
// nil means don't deserialize
exists, err = db.Read("one", nil)
require.NoError(t, err)
require.True(t, exists)
b = false
exists, err = db.Read("two", &b)
require.NoError(t, err)
require.False(t, exists)
require.False(t, b)
// nil means don't deserialize
exists, err = db.Read("two", nil)
require.NoError(t, err)
require.False(t, exists)
}
func TestMultiple(t *testing.T) {
dir, err := ioutil.TempDir("", "jsondb-test-")
require.NoError(t, err)
defer cleanupTempDir(t, dir)
perm := os.FileMode(0600)
documents := map[string]document{
"one": document{"octopus", true},
"two": document{"zebra", false},
"three": document{"clownfish", true},
}
db := jsondb.New(dir, perm)
for name, doc := range documents {
err = db.Write(name, doc)
require.NoError(t, err)
}
names, err := db.List()
require.NoError(t, err)
require.ElementsMatch(t, []string{"one", "two", "three"}, names)
for name, doc := range documents {
var d document
exist, err := db.Read(name, &d)
require.NoError(t, err)
require.True(t, exist)
require.Equalf(t, doc, d, "error retrieving document '%s'", name)
}
}