Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion models/diskReadiness.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func (dr *RealDiskReadiness) isReadyPeriodicCheck(timeout time.Duration, ctx con
}

// run the periodic check again in the background
go dr.isReadyPeriodicCheck(3*time.Minute, ctx)
go dr.isReadyPeriodicCheck(IsReadyPeriodicCheckInterval, ctx)
}()
}

Expand Down Expand Up @@ -203,3 +203,5 @@ func (vdr *VirtualDiskReadiness) IsReadyForce(ctx context.Context) bool {
func (vdr *VirtualDiskReadiness) IsReadyForceNonBlocking(ctx context.Context) bool {
return vdr.forAll(func(dr DiskReadiness) bool { return dr.IsReadyForceNonBlocking(ctx) })
}

var IsReadyPeriodicCheckInterval time.Duration = 3 * time.Minute
7 changes: 5 additions & 2 deletions models/partitioner.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func (p *BalancedPartitioner) FetchDisks(disks []Disk) {
// Load disk list again in case something has changed in volume
p.Disks = make([]Disk, 0)
for _, disk := range disks {
if ComputeFreeSpace(disk) > uint64(p.AbstractPartitioner.Volume.BlockSize) {
if CalculateDiskSpaceFunction(disk) > uint64(p.AbstractPartitioner.Volume.BlockSize) {
p.Disks = append(p.Disks, disk)
}
}
Expand Down Expand Up @@ -259,7 +259,7 @@ func (p *ThroughputPartitioner) FetchDisks(disks []Disk) {

// Compute throughput weights and reset allocations
for i, disk := range p.Disks {
p.Weights[i] = MeasureDiskThroughput(disk)
p.Weights[i] = MeasureDiskThroughputFunction(disk)
p.Allocations[i] = 0
}

Expand All @@ -277,3 +277,6 @@ func NewThroughputPartitioner(volume *Volume) *ThroughputPartitioner {

return &p
}

var CalculateDiskSpaceFunction func(d Disk) uint64 = func(d Disk) uint64 { return ComputeFreeSpace(d) }
var MeasureDiskThroughputFunction func(d Disk) int = func(d Disk) int { return MeasureDiskThroughput(d) }
53 changes: 43 additions & 10 deletions test/unit/mock/mock_disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,35 @@ import (
)

type MockDisk struct {
UUID uuid.UUID
Volume *models.Volume
Name string
SpeedFactor int
UUID uuid.UUID
VirtualDiskUUID uuid.UUID
Volume *models.Volume
Name string
SpeedFactor int

UsedSpace uint64
TotalSpace uint64

CreationTime time.Time
DiskReadiness *MockDiskReadiness

UploadSuccess bool
DownloadSuccess bool
RemoveSuccess bool
}

/* Mandatory Disk interface implementations */

func (d *MockDisk) Upload(blockMetadata *apicalls.BlockMetadata) *apicalls.ErrorWrapper {
time.Sleep(time.Duration(d.SpeedFactor) * time.Millisecond)

if !d.UploadSuccess {
return &apicalls.ErrorWrapper{
Error: fmt.Errorf("test_error"),
Code: "test_code",
}
}

*blockMetadata.Status = constants.BLOCK_STATUS_TRANSFERRED
blockMetadata.CompleteCallback(blockMetadata.UUID, blockMetadata.Status)

Expand All @@ -41,13 +53,27 @@ func (d *MockDisk) Upload(blockMetadata *apicalls.BlockMetadata) *apicalls.Error
func (d *MockDisk) Download(blockMetadata *apicalls.BlockMetadata) *apicalls.ErrorWrapper {
time.Sleep(time.Duration(d.SpeedFactor) * time.Millisecond)

if !d.DownloadSuccess {
return &apicalls.ErrorWrapper{
Error: fmt.Errorf("test_error"),
Code: "test_code",
}
}

*blockMetadata.Status = constants.BLOCK_STATUS_TRANSFERRED
blockMetadata.CompleteCallback(blockMetadata.UUID, blockMetadata.Status)

return nil
}

func (d *MockDisk) Remove(blockMetadata *apicalls.BlockMetadata) *apicalls.ErrorWrapper {
if !d.RemoveSuccess {
return &apicalls.ErrorWrapper{
Error: fmt.Errorf("test_error"),
Code: "test_code",
}
}

*blockMetadata.Status = constants.BLOCK_STATUS_TRANSFERRED
blockMetadata.CompleteCallback(blockMetadata.UUID, blockMetadata.Status)

Expand Down Expand Up @@ -107,11 +133,11 @@ func (d *MockDisk) GetIsVirtualFlag() bool {
}

func (d *MockDisk) SetVirtualDiskUUID(uuid uuid.UUID) {
return
d.VirtualDiskUUID = uuid
}

func (d *MockDisk) GetVirtualDiskUUID() uuid.UUID {
return uuid.Nil
return d.VirtualDiskUUID
}

func (d *MockDisk) SetUsedSpace(usage uint64) {
Expand Down Expand Up @@ -186,25 +212,32 @@ func (d *MockDisk) GetResponse(_disk *dbo.Disk, ctx *gin.Context) *models.DiskRe
return nil
}

type MockDiskReadiness struct{}
type MockDiskReadiness struct {
Readiness bool
}

func (mdr *MockDiskReadiness) IsReady(ctx context.Context) bool {
return true
return mdr.Readiness
}

func (mdr *MockDiskReadiness) IsReadyForce(ctx context.Context) bool {
return true
return mdr.Readiness
}

func (mdr *MockDiskReadiness) IsReadyForceNonBlocking(ctx context.Context) bool {
return true
return mdr.Readiness
}

func NewMockDisk() models.Disk {
var d *MockDisk = new(MockDisk)

d.CreationTime = time.Now()
d.DiskReadiness = new(MockDiskReadiness)
d.DiskReadiness.Readiness = true
d.UUID = uuid.New()
d.RemoveSuccess = true
d.DownloadSuccess = true
d.UploadSuccess = true

return d
}
Expand Down
2 changes: 1 addition & 1 deletion test/unit/mock/mock_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ var Providers []int = []int{

var DummyCredentials []string = []string{
/* SFTP */ "{\n \"Login\": \"dcfs\",\n \"Password\": \"UszatekM*01\",\n \"Host\": \"34.118.20.66\",\n \"Port\": \"2022\",\n \"Path\": \"sftp\"\n }",
/* GDrive */ "{\"accessToken\":\"ya29.a0AX9GBdUNEFRsou1hWgKipZOeKMUKG4VtSk-z1Q2MlMWmhO1RellM13qGK2PhaCS-uMC5GfqBqxC438aupgBsxCu7-X8YjnduqGN0n6AYJsZvFyAFHG-GAWNQQNXx8g0k178_xSLFm_GHbQQQlJY3E8dLcLEpaCgYKAXgSARESFQHUCsbCmTqnF6cvog--D5ERjCNPmQ0163\",\"refreshToken\":\"1//0cM8nAT3TworpCgYIARAAGAwSNwF-L9IrWbYuXsSOSnjhXhOgZFDqY_hxlDuIPi032V96rFWCEoZgxu8jPnEjHGGFtkPPHw-0GU4\"}",
/* GDrive */ "{\"accessToken\":\"ya29.a0AX9GBdVpj8KenvSOugBow2deqM8U-NLj9arLIiWsDbxROTwKssZuXGyFIhw3lhPRFdNBzadTJv50pGgKFXLE-hx1GWeLsh0mUwdB5FenYOLM7p3J-7uwE3TuU1rTkuh-g0dhu2DVuBEqNRbnDUnqzfKimaYKaCgYKAXkSARESFQHUCsbCh_INfojnUtjTcUgltFQ57g0163\",\"refreshToken\":\"1//0c4c82W0JmeVICgYIARAAGAwSNwF-L9IrtukM68LkGTGDXPAzBNW1X-fTl97ICJTCtYXvSxheyqIM0pzDGwoxFyKvxwGL2wkVCbM\"}",
/* OneDrive */ "{\"accessToken\":\"EwBoA8l6BAAUkj1NuJYtTVha+Mogk+HEiPbQo04AAchFRC5PDv5fTwCbjPv/WuQI09Q4Nw4n4OkJsc7NaYnfiC3dT6RkUCUOFdTeegkvpom4UjjIR+SXlkSintNxhBW2giJyTyuXWYrLzip1nz56XRc06i3oKfUMFkY/b7HkZa7KQoiItGV7OqznTv6lUm50qOyhzw7RuHU1sXQ5QSAtVtQlqOYI4O3+vOglcWK+AU6UEytcSbeIpHYbHY+WhEOodClRiTdeqe/IRPcLZeHCe6hkomFNoqJheFtwTpQirzCakNRLPE8uqNz4j4T8YLEeFhlwnQDFaNStVxWXw/V3lQjaWVZ+szJP+NhukBnwEVTiAwEHByKRYW37L+nyB0MDZgAACBWi7LHIguO0OAKCB85qK72YF/9oPRcPAs7hDNx8huTv9cBvwqFSbK9ohYQN/WqMyrwcKpGjtXYxmO9EaTcIFKM0ZWITf62zyQXEp/8p5qvqRL850D3i6f0C94dgGFpKYJaDvpQnU1cbt9d3KDWh3JnQ3P9dDmR2T92ZLXWcKIAa4GnfVknQfULlO4YFvc6MwGZtm57jBpAfZLJ6IlUhuDAHb6xdidcGKJQFh+GdWADQj5/yigBKOCjhUDzoYj0b+Mi+c8hTWOSw+4oBWW0kbmyEQebHF0G9OrIuW9Egm6NAFWvgQQOpalXwyDzUl82xRoNrPz4QKb4gWJrmLrF7PJoVm+V+Vh4MaWkSLtg0hnKZ/Sf4iGlHmD5J2FIyoKq0Q0WB5Khy43USKHsme63VdIzvB61LQ+N7Qqk9Q2RWl1DWYkbBPQLnb/UCf+DZhX2K8fdY6dwiNXya3zB54D+zqv2p0GB+c4jYC0jwhc+J4bYJA0Jt0EBWkoP/sikfD47faDA1C141WYEyT/DC0hx0ws/BZVW4BCxAZTXKR1CVKY+23R4b4tngE0LDcE1YYMViWyllGHSM+YsWr6Kglkqx+QFJaP9WetEp3BI9ocXohsEgKhCpdmE2MHQs/MNCfK7sHbEn54Araq+EZNSXrX8DMdgiaa4veDFEh/lSVike7G3/W/hryRREVLHxW6DatPDbhJBXQYdjYr2kDi8oM7s5/W/CBXRgVfH/0XClKML8bYXRDteJ3hRnBNrWvIc31FUhecvrcAI=\",\"refreshToken\":\"M.R3_BAY.-CQ7xzIkBvl*6*v0Vrzqq89mqsiHkVGnvJpVUUPoz3rjl76x1JDceujKm6Sef*FNJw47VrBCuj10bxzg7WNfX2hmDSjAqEYRzFxjKa2bH54JejTpP3CPrESkAQg79DMJMDyrxyyCNXbkGB8g6hdtBb7BoTN9tpYL7J2IVh9kwla7D2GxPv36hbxG208!5VK9mNR4N!qbpziol!nVbZBEoPM3xdYFt6ZP02NmCYjmstyoOmTS5VkKjOu9V2!J78z2v9bu0U!*r!JKXL3woLkHpegx8OnMmGJh*9XVk8QOom2Z8\"}",
}

Expand Down
18 changes: 18 additions & 0 deletions test/unit/mock/mock_volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ var VolumeSettings dbo.VolumeSettings = dbo.VolumeSettings{
FilePartition: constants.PARTITION_TYPE_BALANCED,
}

var BackupVolumeSettings dbo.VolumeSettings = dbo.VolumeSettings{
Backup: constants.BACKUP_TYPE_RAID_1,
Encryption: constants.ENCRYPTION_TYPE_NO_ENCRYPTION,
FilePartition: constants.PARTITION_TYPE_BALANCED,
}

var VolumeDBO *dbo.Volume = &dbo.Volume{
AbstractDatabaseObject: dbo.AbstractDatabaseObject{
UUID: VolumeUUID,
Expand All @@ -29,6 +35,18 @@ var VolumeDBO *dbo.Volume = &dbo.Volume{
User: *UserDBO,
}

var BackupVolumeDBO *dbo.Volume = &dbo.Volume{
AbstractDatabaseObject: dbo.AbstractDatabaseObject{
UUID: VolumeUUID,
},
Name: "MockVolume",
UserUUID: UserUUID,
VolumeSettings: BackupVolumeSettings,
CreatedAt: time.Time{},
DeletedAt: gorm.DeletedAt{},
User: *UserDBO,
}

var Volume *models.Volume = &models.Volume{
UUID: VolumeUUID,
BlockSize: constants.DEFAULT_VOLUME_BLOCK_SIZE,
Expand Down
25 changes: 25 additions & 0 deletions test/unit/ut_block_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package unit

import (
"dcfs/models"
"dcfs/test/unit/mock"
"github.com/google/uuid"
. "github.com/smartystreets/goconvey/convey"
"testing"
)

func TestNewBlockFromDBO(t *testing.T) {
blockDBO := mock.GetBlockDBOs(1, uuid.New(), uuid.New())[0]
block := models.NewBlockFromDBO(&blockDBO)

Convey("The block fields are reflected properly in the final object", t, func() {
So(block.UUID, ShouldEqual, blockDBO.UUID)
So(block.UserUUID, ShouldEqual, blockDBO.UserUUID)
So(block.File, ShouldEqual, nil)
So(block.Disk, ShouldEqual, nil)
So(block.Size, ShouldEqual, blockDBO.Size)
So(block.Checksum, ShouldEqual, blockDBO.Checksum)
So(block.Status, ShouldEqual, 0)
So(block.Order, ShouldEqual, blockDBO.Order)
})
}
33 changes: 33 additions & 0 deletions test/unit/ut_diskReadiness_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package unit

import (
"context"
"dcfs/models"
. "github.com/smartystreets/goconvey/convey"
"testing"
"time"
)

// this model should be excluded from unit testing completely,
//thus the tests here only validate this file in the coverage

func TestCompoundDiskReadiness(t *testing.T) {
r := models.NewRealDiskReadiness(func(ctx context.Context) bool { return true }, func() bool { return true })
virtual := models.NewVirtualDiskReadiness(r)

models.IsReadyPeriodicCheckInterval = time.Second
r.IsReady(nil)
r.IsReadyForce(nil)
r.IsReadyForceNonBlocking(nil)

virtual.IsReady(nil)
virtual.IsReadyForce(nil)
virtual.IsReadyForceNonBlocking(nil)

virtual = models.NewVirtualDiskReadiness()
virtual = models.NewVirtualDiskReadiness(nil)

Convey("This method did not cause any panics or errors", t, func() {
So(true, ShouldEqual, true)
})
}
17 changes: 17 additions & 0 deletions test/unit/ut_disk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ func TestCreateDiskAndGetDiskDbo(t *testing.T) {
So(disks[0].TotalSpace, ShouldEqual, diskDBO.TotalSpace)
So(disks[0].CreatedAt, ShouldEqual, diskDBO.CreatedAt)
})

Convey("Will not be able to create disk if the type is not supported", t, func() {
md := models.CreateDiskMetadata{
Disk: &disks[0],
Volume: volume,
}

md.Disk.Provider.Type = 100

So(models.CreateDisk(md), ShouldEqual, nil)
})

Convey("The database call should be correct", t, func() {
So(mock.DBMock.ExpectationsWereMet(), ShouldEqual, nil)
})
Expand All @@ -48,6 +60,10 @@ func TestCreateDiskFromUUID(t *testing.T) {
// WithArgs(disks[0].UUID).
// WillReturnRows(mock.DiskRow(&disks[0]))

// disable partitioner calculation of real disk space
oldCalculateDiskSpaceFunction := models.CalculateDiskSpaceFunction
models.CalculateDiskSpaceFunction = func(d models.Disk) uint64 { return uint64(2 * constants.DEFAULT_VOLUME_BLOCK_SIZE) }

Convey("CreateDiskFromUUID function works correctly", t, func() {
Convey("Should return nil if the disk does not exist", func() {
mock.DBMock.ExpectQuery(regexp.QuoteMeta("SELECT * FROM `disks` WHERE uuid = ?")).
Expand All @@ -66,6 +82,7 @@ func TestCreateDiskFromUUID(t *testing.T) {

models.Transport.FileDownloadQueue.RemoveEnqueuedInstance(fileDBO.UUID)
models.Transport.ActiveVolumes.RemoveEnqueuedInstance(mock.VolumeUUID)
models.CalculateDiskSpaceFunction = oldCalculateDiskSpaceFunction
}

func TestComputeFreeSpace(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions test/unit/ut_file_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package unit
41 changes: 41 additions & 0 deletions test/unit/ut_pagination_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package unit

import (
"dcfs/models"
"dcfs/test/unit/mock"
. "github.com/smartystreets/goconvey/convey"
"testing"
)

func TestPaginate(t *testing.T) {
objects := []interface{}{
mock.NewMockDisk(),
mock.NewMockDisk(),
mock.NewMockDisk(),
mock.NewMockDisk(),
mock.NewMockDisk(),
mock.NewMockDisk(),
mock.NewMockDisk(),
mock.NewMockDisk(),
mock.NewMockDisk(),
mock.NewMockDisk()}
data := models.Paginate(objects, 1, 2)

Convey("The pagination data has been split properly", t, func() {
So(data.Pagination.PerPage, ShouldEqual, 2)
So(data.Pagination.TotalPages, ShouldEqual, 5)
So(data.Pagination.CurrentPage, ShouldEqual, 1)
So(data.Pagination.RecordsOnPage, ShouldEqual, 2)
So(data.Pagination.TotalRecords, ShouldEqual, 10)
})

data = models.Paginate(objects, 0, 2)

Convey("The pagination data has been split properly", t, func() {
So(data.Pagination.PerPage, ShouldEqual, 2)
So(data.Pagination.TotalPages, ShouldEqual, 5)
So(data.Pagination.CurrentPage, ShouldEqual, 0)
So(data.Pagination.RecordsOnPage, ShouldEqual, 0)
So(data.Pagination.TotalRecords, ShouldEqual, 10)
})
}
11 changes: 11 additions & 0 deletions test/unit/ut_partitioner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,11 @@ func TestThroughputPartitioner_FullDisks(t *testing.T) {
}

func TestThroughputPartitioner_AssignBlocks(t *testing.T) {
oldMeasureThroughputFunction := models.MeasureDiskThroughputFunction
models.MeasureDiskThroughputFunction = func(d models.Disk) int { return 100 }
oldCalculateDiskSpaceFunction := models.CalculateDiskSpaceFunction
models.CalculateDiskSpaceFunction = func(d models.Disk) uint64 { return uint64(2 * constants.DEFAULT_VOLUME_BLOCK_SIZE) }

disks := mock.GetDiskDBOs(2)

mock.VolumeDBO.VolumeSettings.FilePartition = constants.PARTITION_TYPE_THROUGHPUT
Expand Down Expand Up @@ -351,6 +356,9 @@ func TestThroughputPartitioner_AssignBlocks(t *testing.T) {
Convey("The database call should be correct", t, func() {
So(mock.DBMock.ExpectationsWereMet(), ShouldEqual, nil)
})

models.MeasureDiskThroughputFunction = oldMeasureThroughputFunction
models.CalculateDiskSpaceFunction = oldCalculateDiskSpaceFunction
}

func TestPartitionerFactory(t *testing.T) {
Expand Down Expand Up @@ -516,4 +524,7 @@ func init() {
mockProvider.Name = "Mock provider"
mockProvider.Type = PROVIDER_TYPE_MOCK
mockProvider.Logo = "Mock logo"

// disable throughput partitioners
models.RefreshPartitionerFunc = func(v *models.Volume) {}
}
Loading