Use is. tests and fmt

master
Caj Larsson 3 years ago
parent 8a0e6b80e3
commit e6e2f372dd

@ -1,16 +1,16 @@
package namespace
import (
"time"
"errors"
"time"
)
type Namespace struct {
ID int64
Name string
LastSeen time.Time
ID int64
Name string
LastSeen time.Time
AllowanceDuration time.Duration
FileQuota FileSizeQuota
FileQuota FileSizeQuota
}
var (

@ -6,7 +6,7 @@ var (
ErrNoNamespace = errors.New("that namespace does not exist")
)
type Repository interface{
type Repository interface {
Create(namespace Namespace) (*Namespace, error)
All() ([]Namespace, error)
GetByName(name string) (*Namespace, error)

@ -1,13 +1,12 @@
package namespace
type FileSizeQuota struct {
AllowanceKB int64
AllowanceKB int64
CurrentUsage int64
}
func (f *FileSizeQuota) Allows(size int64) bool {
return f.CurrentUsage + size <= f.AllowanceKB
return f.CurrentUsage+size <= f.AllowanceKB
}
func (f *FileSizeQuota) Add(size int64) error {

@ -1,57 +1,37 @@
package namespace
import (
"github.com/matryer/is"
"testing"
)
func TestQuota(t *testing.T) {
quota := FileSizeQuota { 1000, 0 }
if !quota.Allows(1000) {
t.Errorf("It should allow filling completely")
}
if quota.Allows(1001) {
t.Errorf("It should not allow filling completely")
}
is := is.New(t)
quota := FileSizeQuota{1000, 0}
is.True(quota.Allows(1000))
is.True(!quota.Allows(1001))
}
func TestQuotaManipulation(t *testing.T) {
quota := FileSizeQuota { 1000, 0 }
is := is.New(t)
quota := FileSizeQuota{1000, 0}
if quota.Add(500) != nil {
t.Errorf("It should allow adding")
}
is.NoErr(quota.Add(500))
if quota.CurrentUsage != 500 {
t.Errorf("It should add the usage correctly")
}
is.Equal(quota.CurrentUsage, int64(500))
if quota.Add(500) != nil {
t.Errorf("It should allow adding up to the limit")
}
is.NoErr(quota.Add(500))
if quota.Add(1) != ErrExceedQuota {
t.Errorf("It should not allow adding beyond limit")
}
is.Equal(quota.Add(1), ErrExceedQuota)
if quota.CurrentUsage != 1000 {
t.Errorf("It should not overtaxed after failure to add")
}
is.Equal(quota.CurrentUsage, int64(1000))
if quota.Remove(1001) != ErrQuotaInvalid {
t.Errorf("It should not allow reducing further than 0")
}
is.Equal(quota.Remove(1001), ErrQuotaInvalid)
if quota.CurrentUsage != 1000 {
t.Errorf("It should not overtaxed after failure to remove")
}
is.Equal(quota.CurrentUsage, int64(1000))
if quota.Remove(1000) != nil {
t.Errorf("It should allow reducing to 0")
}
is.NoErr(quota.Remove(1000))
if quota.CurrentUsage != 0 {
t.Errorf("It should reduce accurately")
}
is.Equal(quota.CurrentUsage, int64(0))
}

@ -1,21 +1,20 @@
package dataswamp
import (
"caj-larsson/bog/dataswamp/namespace"
"caj-larsson/bog/dataswamp/swampfile"
"io"
"time"
"strconv"
"strings"
"path"
"path/filepath"
"caj-larsson/bog/dataswamp/namespace"
"caj-larsson/bog/dataswamp/swampfile"
"strconv"
"strings"
"time"
)
type SwampFileService struct {
namespace_repo namespace.Repository
swamp_file_repo swampfile.Repository
default_allowance_bytes int64
namespace_repo namespace.Repository
swamp_file_repo swampfile.Repository
default_allowance_bytes int64
default_allowance_duration time.Duration
}
@ -25,19 +24,19 @@ func NewSwampFileService(
da_bytes int64,
da_duration time.Duration,
) SwampFileService {
return SwampFileService {namespace_repo, swamp_file_repo, da_bytes, da_duration}
return SwampFileService{namespace_repo, swamp_file_repo, da_bytes, da_duration}
}
func (s SwampFileService) getOrCreateNs(namespace_in string) *namespace.Namespace{
func (s SwampFileService) getOrCreateNs(namespace_in string) *namespace.Namespace {
ns, err := s.namespace_repo.GetByName(namespace_in)
if err == namespace.ErrNotExists {
new_ns := namespace.Namespace {
new_ns := namespace.Namespace{
0,
namespace_in,
time.Now(),
s.default_allowance_duration,
namespace.FileSizeQuota { s.default_allowance_bytes, 0 },
namespace.FileSizeQuota{s.default_allowance_bytes, 0},
}
created_ns, err := s.namespace_repo.Create(new_ns)
@ -77,11 +76,11 @@ func (s SwampFileService) SaveFile(ref swampfile.FileReference, src io.Reader, s
}
func (s SwampFileService) OpenOutFile(ref swampfile.FileReference) (swampfile.SwampOutFile, error) {
ns, err := s.namespace_repo.GetByName(ref.UserAgent)
ns := s.getOrCreateNs(ref.UserAgent)
if err == namespace.ErrNotExists {
return nil, err
}
// if err == namespace.ErrNotExists {
// return nil, err
// }
f, err := s.swamp_file_repo.Open(ref.Path, strconv.FormatInt(ns.ID, 10))

@ -1,20 +1,19 @@
package dataswamp
import (
"time"
"bytes"
"testing"
"github.com/matryer/is"
"caj-larsson/bog/dataswamp/swampfile"
"caj-larsson/bog/dataswamp/namespace"
"github.com/matryer/is"
"testing"
"time"
// "caj-larsson/bog/dataswamp/namespace"
m_namespace "caj-larsson/bog/infrastructure/memory/namespace"
m_swampfile "caj-larsson/bog/infrastructure/memory/swampfile"
)
var file_ref1 = swampfile.FileReference { "ptah1", "ua1" }
var file_ref2 = swampfile.FileReference { "path1", "ua2" }
var file_ref3 = swampfile.FileReference { "path2", "ua1" }
var file_ref1 = swampfile.FileReference{"ptah1", "ua1"}
var file_ref2 = swampfile.FileReference{"path1", "ua2"}
var file_ref3 = swampfile.FileReference{"path2", "ua1"}
func NewTestSwampFileService() SwampFileService {
file_repo := m_swampfile.NewRepository()
@ -23,24 +22,23 @@ func NewTestSwampFileService() SwampFileService {
}
func TestFileDontExist(t *testing.T) {
is := is.New(t)
s := NewTestSwampFileService()
outfile, err := s.OpenOutFile(file_ref1)
if outfile != nil && err != swampfile.ErrNotExists {
t.Errorf("File shall not exist by default")
}
is.True(err == swampfile.ErrNotExists)
is.True(outfile == nil)
}
func TestFileIsStored(t *testing.T) {
is := is.New(t)
s := NewTestSwampFileService()
fakefile := bytes.NewBufferString("My bog data")
err := s.SaveFile(file_ref1, fakefile, int64(fakefile.Len()))
if err != nil {
t.Errorf("A small file should be writable %s", err)
}
is.NoErr(err)
largefakefile := bytes.NewBufferString("")
@ -50,14 +48,11 @@ func TestFileIsStored(t *testing.T) {
err = s.SaveFile(file_ref3, largefakefile, int64(largefakefile.Len()))
if err != namespace.ErrExceedQuota {
t.Errorf("too large files should not be excepted")
}
is.Equal(err, swampfile.ErrExceedQuota)
}
func TestFileIsReadBack(t *testing.T) {
is := is.New(t)
s := NewTestSwampFileService()
infile := bytes.NewBufferString("My bog data")
@ -69,13 +64,11 @@ func TestFileIsReadBack(t *testing.T) {
outfile := bytes.NewBufferString("")
_, _ = outfile.ReadFrom(outswampfile)
if outfile.String() != "My bog data" {
t.Errorf("file corrupted")
}
is.Equal(outfile.String(), "My bog data")
}
func TestUAIsolation(t *testing.T) {
is := is.New(t)
s := NewTestSwampFileService()
ns1_file := bytes.NewBufferString("My bog data ua1")
@ -89,12 +82,9 @@ func TestUAIsolation(t *testing.T) {
outfile := bytes.NewBufferString("")
_, _ = outfile.ReadFrom(outswampfile)
if outfile.String() != "My bog data ua1" {
t.Errorf("file corrupted")
}
is.Equal(outfile.String(), "My bog data ua1")
}
func TestCleanPath(t *testing.T) {
is := is.New(t)

@ -1,15 +1,15 @@
package swampfile
import (
"time"
"errors"
"time"
)
type SwampFile struct {
UserAgentId int64
Path string
Size int64
CreatedAt time.Time
Path string
Size int64
CreatedAt time.Time
}
var (

@ -1,29 +1,27 @@
package swampfile
import (
"github.com/matryer/is"
"testing"
)
func RepositoryContract(fac func() Repository, t *testing.T) {
basicFileOperationContract(fac, t)
}
func basicFileOperationContract(fac func() Repository, t *testing.T) {
is := is.New(t)
repo := fac()
not_file, err := repo.Open("doesnot", "exist")
if err != ErrNotExists || not_file != nil{
t.Errorf("Must raise not exists and file must not open")
}
is.Equal(err, ErrNotExists)
is.Equal(not_file, nil)
new_file, err := repo.Create("newfile.new", "ua1")
if err != nil || new_file == nil {
t.Errorf("Create ")
}
is.NoErr(err)
is.True(new_file != nil)
var testdata = "testingdata"
@ -32,17 +30,14 @@ func basicFileOperationContract(fac func() Repository, t *testing.T) {
reopened_file, err := repo.Open("newfile.new", "ua1")
if err != nil || reopened_file == nil{
t.Errorf("Must open existing files")
}
is.NoErr(err)
is.True(reopened_file != nil)
readback := make([]byte, 128)
size, err := reopened_file.Read(readback)
if string(readback[0:size]) != testdata {
t.Errorf("Must contain previously stored data '%s' '%s'", string(readback), testdata)
}
is.Equal(string(readback[0:size]), testdata)
reopened_file.Close()
@ -50,7 +45,6 @@ func basicFileOperationContract(fac func() Repository, t *testing.T) {
deleted_file, err := repo.Open("newfile.new", "ua1")
if err != ErrNotExists || deleted_file != nil{
t.Errorf("Musn't open deleted files")
}
is.Equal(err, ErrNotExists)
is.True(deleted_file == nil)
}

@ -1,17 +1,17 @@
package swampfile
import (
"time"
"caj-larsson/bog/dataswamp/swampfile"
"os"
"path"
"caj-larsson/bog/dataswamp/swampfile"
"time"
)
type FileSystemSwampFileData struct {
path string
size int64
path string
size int64
mod_time time.Time
file *os.File
file *os.File
}
func (f FileSystemSwampFileData) Read(p []byte) (int, error) {
@ -38,7 +38,7 @@ func (f FileSystemSwampFileData) Size() int64 {
return f.size
}
func (f FileSystemSwampFileData) Modified() time.Time{
func (f FileSystemSwampFileData) Modified() time.Time {
return time.Now()
}
@ -66,7 +66,7 @@ func (f Repository) Create(filename string, namespace_ns string) (swampfile.Swam
panic(err)
}
bfd := FileSystemSwampFileData {filename, stat_info.Size(), stat_info.ModTime(), file}
bfd := FileSystemSwampFileData{filename, stat_info.Size(), stat_info.ModTime(), file}
return bfd, nil
}
@ -82,7 +82,7 @@ func (f Repository) Open(filename string, namespace_ns string) (swampfile.SwampO
return nil, swampfile.ErrNotExists
}
bfd := FileSystemSwampFileData {filename, 0, time.Now(), file}
bfd := FileSystemSwampFileData{filename, 0, time.Now(), file}
return bfd, nil
}

@ -1,9 +1,9 @@
package swampfile
import (
"caj-larsson/bog/dataswamp/swampfile"
"path"
"testing"
"caj-larsson/bog/dataswamp/swampfile"
)
func TestFsFileRepo(t *testing.T) {
@ -11,7 +11,7 @@ func TestFsFileRepo(t *testing.T) {
var fac = func() swampfile.Repository {
r := t.TempDir()
d := path.Join(r, "fs")
repo := Repository { d }
repo := Repository{d}
return &repo
}

@ -1,15 +1,14 @@
package memory
package namespace
import (
// "time"
"caj-larsson/bog/dataswamp/namespace"
)
type Repository struct {
IdIdx map[int64] *namespace.Namespace
NameIdx map[string] *namespace.Namespace
NextId int64
IdIdx map[int64]*namespace.Namespace
NameIdx map[string]*namespace.Namespace
NextId int64
}
func NewRepository() *Repository {
@ -29,17 +28,15 @@ func (r *Repository) Create(ns namespace.Namespace) (*namespace.Namespace, error
return &ns, nil
}
func (r *Repository) All() ([]namespace.Namespace, error) {
ns := make([]namespace.Namespace, 0, len(r.IdIdx))
for _, value := range r.IdIdx {
for _, value := range r.IdIdx {
ns = append(ns, *value)
}
return ns, nil
}
func (r *Repository) GetByName(name string) (*namespace.Namespace, error) {
ns, exists := r.NameIdx[name]
if exists {
@ -48,7 +45,6 @@ func (r *Repository) GetByName(name string) (*namespace.Namespace, error) {
return nil, namespace.ErrNotExists
}
func (r *Repository) Update(id int64, ns namespace.Namespace) (*namespace.Namespace, error) {
original := *r.IdIdx[id]
ns.ID = id
@ -57,7 +53,6 @@ func (r *Repository) Update(id int64, ns namespace.Namespace) (*namespace.Namesp
return &ns, nil
}
func (r *Repository) Delete(id int64) error {
original := *r.IdIdx[id]
delete(r.NameIdx, original.Name)

@ -1,52 +1,43 @@
package memory
package namespace
import (
"caj-larsson/bog/dataswamp/namespace"
"github.com/matryer/is"
"testing"
"time"
"caj-larsson/bog/dataswamp/namespace"
)
func TestUserAgentRepo(t *testing.T) {
is := is.New(t)
r := NewRepository()
all, err := r.All()
if len(all) != 0 && err != nil {
t.Errorf("New repo should be empty")
}
ns := namespace.Namespace {23, "n1", time.Now(), time.Duration(time.Hour * 3), namespace.FileSizeQuota {1000, 0} }
is.NoErr(err)
is.Equal(len(all), 0)
ns := namespace.Namespace{23, "n1", time.Now(), time.Duration(time.Hour * 3), namespace.FileSizeQuota{1000, 0}}
ns1, _ := r.Create(ns)
ns.Name = "n2"
ns2, _ := r.Create(ns)
if ns1 == ns2 {
t.Errorf("Must create unique items")
}
is.True(ns1 != ns2)
all, err = r.All()
if len(all) != 2 && err != nil {
t.Errorf("After adding there should be two Useragent")
}
is.NoErr(err)
is.Equal(len(all), 2)
if ns.ID != 23 {
t.Errorf("It does not change the original UserAgent")
}
is.Equal(ns.ID, int64(23))
ns3, _ := r.GetByName("n2")
if ns3 != ns2 {
t.Errorf("It the correct ns is acquired")
}
is.Equal(ns3, ns2)
if r.Delete(ns2.ID) != nil {
t.Errorf("Must delete without error")
}
is.NoErr(r.Delete(ns2.ID))
all, err = r.All()
if len(all) != 1 && err != nil {
t.Errorf("After deleting one there should be one NS ")
}
is.NoErr(err)
is.Equal(len(all), 1)
}

@ -1,18 +1,17 @@
package swampfile
import (
"time"
"path"
"os"
"path"
"time"
// "io"
"github.com/spf13/afero"
"caj-larsson/bog/dataswamp/swampfile"
"github.com/spf13/afero"
)
type SwampFile struct {
filename string
file afero.File
file afero.File
}
func (f SwampFile) Path() string {
@ -51,7 +50,7 @@ type Repository struct {
}
func NewRepository() swampfile.Repository {
return Repository { afero.NewMemMapFs() }
return Repository{afero.NewMemMapFs()}
}
func (r Repository) Create(filename string, namespace_stub string) (swampfile.SwampInFile, error) {
@ -64,7 +63,7 @@ func (r Repository) Create(filename string, namespace_stub string) (swampfile.Sw
panic(err)
}
bf := SwampFile {filename, file}
bf := SwampFile{filename, file}
return bf, nil
}
@ -80,7 +79,7 @@ func (r Repository) Open(filename string, namespace_stub string) (swampfile.Swam
return nil, swampfile.ErrNotExists
}
bf := SwampFile {filename, file}
bf := SwampFile{filename, file}
return bf, nil
}

@ -1,11 +1,10 @@
package swampfile
import (
"testing"
"caj-larsson/bog/dataswamp/swampfile"
"testing"
)
func TestFileRepo(t *testing.T) {
swampfile.RepositoryContract(NewRepository, t)
}

@ -1,9 +1,9 @@
package namespace
import (
"caj-larsson/bog/dataswamp/namespace"
"errors"
"time"
"caj-larsson/bog/dataswamp/namespace"
)
type NamespaceRecord struct {
@ -29,7 +29,7 @@ func (r *NamespaceRecord) toEntity() (*namespace.Namespace, error) {
ns.Name = r.Name
ns.LastSeen = lastseen
ns.AllowanceDuration = time.Duration(r.AllowanceSeconds * int64(time.Second))
ns.FileQuota = namespace.FileSizeQuota { r.QuotaKB, r.QuotaUsedKB }
ns.FileQuota = namespace.FileSizeQuota{r.QuotaKB, r.QuotaUsedKB}
return ns, err
}

@ -12,7 +12,7 @@ type Repository struct {
}
func NewRepository(filename string) *Repository {
db, err := sql.Open("sqlite3", filename)
db, err := sql.Open("sqlite3", filename)
if err != nil {
panic(err)
}

@ -2,15 +2,15 @@ package main
import (
"caj-larsson/bog/server"
"io/ioutil"
"fmt"
"io/ioutil"
)
func main() {
content, err := ioutil.ReadFile("default.toml")
if err != nil {
panic(err)
panic(err)
}
config, err := server.ConfigFromToml(string(content))

@ -1,15 +1,15 @@
package server
import (
"net/http"
"fmt"
"net/http"
"strconv"
// "io"
"caj-larsson/bog/dataswamp"
"caj-larsson/bog/dataswamp/namespace"
"caj-larsson/bog/dataswamp/swampfile"
sql_namespace "caj-larsson/bog/infrastructure/sqlite/namespace"
fs_swampfile "caj-larsson/bog/infrastructure/fs/swampfile"
sql_namespace "caj-larsson/bog/infrastructure/sqlite/namespace"
)
type Router interface {
@ -18,18 +18,18 @@ type Router interface {
}
type Bog struct {
router Router
router Router
file_service dataswamp.SwampFileService
address string
address string
}
func buildFileDataRepository(config FileConfig) swampfile.Repository{
func buildFileDataRepository(config FileConfig) swampfile.Repository {
fsSwampfileRepo := new(fs_swampfile.Repository)
fsSwampfileRepo.Root = config.Path
return fsSwampfileRepo
}
func buildUserAgentRepository(config DatabaseConfig) namespace.Repository{
func buildUserAgentRepository(config DatabaseConfig) namespace.Repository {
if config.Backend != "sqlite" {
panic("Can only handle sqlite")
}
@ -42,7 +42,7 @@ func (b *Bog) fileHandler(w http.ResponseWriter, r *http.Request) {
return
}
ref := swampfile.FileReference {r.URL.Path, r.Header["User-Agent"][0]}
ref := swampfile.FileReference{r.URL.Path, r.Header["User-Agent"][0]}
switch r.Method {
case "GET":
@ -82,7 +82,6 @@ func (b *Bog) routes() {
b.router.HandleFunc("/", b.fileHandler)
}
func New(config *Configuration) *Bog {
b := new(Bog)
b.address = config.bindAddress()

@ -2,39 +2,37 @@ package server
import (
"testing"
// "fmt"
// "net/http/httptest"
// "net/http"
// "strings"
// "time"
// "caj-larsson/bog/domain_dataswamp"
// "fmt"
"caj-larsson/bog/dataswamp"
"caj-larsson/bog/infrastructure/memory/namespace"
"caj-larsson/bog/infrastructure/memory/swampfile"
"github.com/matryer/is"
"net/http"
"net/http/httptest"
"strings"
"time"
)
func TestApplication(t *testing.T) {
is := is.New(t)
file_service := dataswamp.NewSwampFileService(
namespace.NewRepository(),
swampfile.NewRepository(),
1000,
time.Hour,
)
// file_service := domain_dataswamp.NewBogFileService(
// mock.NewMockUserAgentRepository(),
// mock.NewMockFileRepository(),
// 1000,
// time.Hour,
// )
// bog := Bog {
// router: new(http.ServeMux),
// file_service: file_service,
// address: "fake",
// }
// bog.routes()
// req := httptest.NewRequest("POST", "/apath", strings.NewReader("testdata"))
// req.Header.Add("User-Agent", "testingclient")
// req.Header.Add("Content-Length", "8")
// w := httptest.NewRecorder()
// bog.router.ServeHTTP(w, req)
bog := Bog{
router: new(http.ServeMux),
file_service: file_service,
address: "fake",
}
bog.routes()
req := httptest.NewRequest("POST", "/apath", strings.NewReader("testdata"))
req.Header.Add("User-Agent", "testingclient")
req.Header.Add("Content-Length", "8")
w := httptest.NewRecorder()
bog.router.ServeHTTP(w, req)
// if (w.Code != 200){
// fmt.Printf("%v", w)
// t.Error("not ok")
// }
is.Equal(w.Code, 200)
}

@ -2,13 +2,11 @@ package server
import (
"fmt"
"time"
"github.com/BurntSushi/toml"
"github.com/c2h5oh/datasize"
"time"
)
func (qc QuotaConfig) ParsedSizeBytes() int64 {
var v datasize.ByteSize
@ -38,40 +36,35 @@ func (qc QuotaConfig) ParsedDuration() time.Duration {
}
type QuotaConfig struct {
DefaultSize string `toml:"default_size"`
DefaultSize string `toml:"default_size"`
DefaultDuration string `toml:"default_duration"`
}
type ServerConfig struct {
Port int64
Host string
}
type FileConfig struct {
Path string
}
type DatabaseConfig struct {
Backend string
Backend string
Connection string
}
type Configuration struct {
Server ServerConfig
File FileConfig
Server ServerConfig
File FileConfig
Database DatabaseConfig
Quota QuotaConfig
Quota QuotaConfig
}
func (c *Configuration) bindAddress() string {
return fmt.Sprintf("%s:%d", c.Server.Host, c.Server.Port)
}
func ConfigFromToml(toml_data string) (*Configuration, error) {
var config Configuration

@ -1,15 +1,15 @@
package server
import (
"time"
"github.com/matryer/is"
"testing"
"time"
)
func TestConfiguration(t *testing.T) {
is := is.New(t)
c, _ := ConfigFromToml(
`[server]
`[server]
port = 8002
host = "127.0.0.1"
@ -25,19 +25,8 @@ func TestConfiguration(t *testing.T) {
default_duration = "72h"`,
)
if c.Server.Port != 8002 {
t.Errorf("port parsing failed")
}
if c.Server.Host != "127.0.0.1" {
t.Errorf("host parsing failed")
}
if c.Quota.ParsedSizeBytes() != 1024 * 1024 {
t.Errorf("quota size parsing failed")
}
if c.Quota.ParsedDuration() != time.Duration(time.Hour * 72) {
t.Errorf("quota size parsing failed")
}
is.Equal(c.Server.Port, int64(8002))
is.Equal(c.Server.Host, "127.0.0.1")
is.Equal(c.Quota.ParsedSizeBytes(), int64(1024*1024))
is.Equal(c.Quota.ParsedDuration(), time.Duration(time.Hour*72))
}

Loading…
Cancel
Save