Dragonfly2
1476 строк · 40.3 Кб
1/*
2* Copyright 2022 The Dragonfly Authors
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16
17package storage18
19import (20"fmt"21"io/fs"22"os"23"path/filepath"24"reflect"25"regexp"26"testing"27"time"28
29"github.com/gocarina/gocsv"30"github.com/stretchr/testify/assert"31
32"d7y.io/dragonfly/v2/scheduler/config"33"d7y.io/dragonfly/v2/scheduler/resource"34)
35
36var (37mockTask = Task{38ID: "1",39URL: "example.com",40Type: "normal",41ContentLength: 2048,42TotalPieceCount: 1,43BackToSourceLimit: 10,44BackToSourcePeerCount: 2,45State: "Succeeded",46CreatedAt: time.Now().UnixNano(),47UpdatedAt: time.Now().UnixNano(),48}49
50mockHost = Host{51ID: "2",52Type: "normal",53Hostname: "localhost",54IP: "127.0.0.1",55Port: 8080,56DownloadPort: 8081,57OS: "linux",58Platform: "ubuntu",59PlatformFamily: "debian",60PlatformVersion: "1.0.0",61KernelVersion: "1.0.0",62ConcurrentUploadLimit: 100,63ConcurrentUploadCount: 40,64UploadCount: 20,65UploadFailedCount: 3,66CPU: resource.CPU{67LogicalCount: 24,68PhysicalCount: 12,69Percent: 0.8,70ProcessPercent: 0.4,71Times: resource.CPUTimes{72User: 100,73System: 101,74Idle: 102,75Nice: 103,76Iowait: 104,77Irq: 105,78Softirq: 106,79Steal: 107,80Guest: 108,81GuestNice: 109,82},83},84Memory: resource.Memory{85Total: 20,86Available: 19,87Used: 16,88UsedPercent: 0.7,89ProcessUsedPercent: 0.2,90Free: 15,91},92Network: resource.Network{93TCPConnectionCount: 400,94UploadTCPConnectionCount: 200,95Location: "china",96IDC: "e1",97},98Disk: resource.Disk{99Total: 100,100Free: 88,101Used: 56,102UsedPercent: 0.9,103InodesTotal: 200,104InodesUsed: 180,105InodesFree: 160,106InodesUsedPercent: 0.6,107},108Build: resource.Build{109GitVersion: "3.0.0",110GitCommit: "2bf4d5e",111GoVersion: "1.19",112Platform: "linux",113},114SchedulerClusterID: 1,115CreatedAt: time.Now().UnixNano(),116UpdatedAt: time.Now().UnixNano(),117}118
119mockPiece = Piece{120Length: 20,121Cost: 10,122CreatedAt: time.Now().UnixNano(),123}124
125mockPieces = append(make([]Piece, 9), mockPiece)126
127mockParent = Parent{128ID: "4",129Tag: "m",130Application: "db",131State: "Succeeded",132Cost: 1000,133UploadPieceCount: 10,134FinishedPieceCount: 10,135Host: mockHost,136Pieces: mockPieces,137CreatedAt: time.Now().UnixNano(),138UpdatedAt: time.Now().UnixNano(),139}140
141mockParents = append(make([]Parent, 19), mockParent)142
143mockDownload = Download{144ID: "5",145Tag: "d",146Application: "mq",147State: "Succeeded",148Error: Error{149Code: "unknow",150Message: "unknow",151},152Cost: 1000,153FinishedPieceCount: 10,154Task: mockTask,155Host: mockHost,156Parents: mockParents,157CreatedAt: time.Now().UnixNano(),158UpdatedAt: time.Now().UnixNano(),159}160
161mockSrcHost = SrcHost{162ID: "3",163Type: "super",164Hostname: "foo",165IP: "127.0.0.1",166Port: 8080,167Network: resource.Network{168TCPConnectionCount: 400,169UploadTCPConnectionCount: 200,170Location: "china",171IDC: "e1",172},173}174
175mockDestHost = DestHost{176ID: "2",177Type: "normal",178Hostname: "localhost",179IP: "127.0.0.1",180Port: 8080,181Network: resource.Network{182TCPConnectionCount: 400,183UploadTCPConnectionCount: 200,184Location: "china",185IDC: "e1",186},187Probes: Probes{188AverageRTT: 10,189CreatedAt: time.Now().UnixNano(),190UpdatedAt: time.Now().UnixNano(),191},192}193
194mockDestHosts = []DestHost{mockDestHost, mockDestHost, mockDestHost, mockDestHost, mockDestHost}195
196mockNetworkTopology = NetworkTopology{197ID: "6",198Host: mockSrcHost,199DestHosts: mockDestHosts,200CreatedAt: time.Now().UnixNano(),201}202)
203
204func TestStorage_New(t *testing.T) {205tests := []struct {206name string207baseDir string208expect func(t *testing.T, s Storage, err error)209}{210{211name: "new storage",212baseDir: os.TempDir(),213expect: func(t *testing.T, s Storage, err error) {214assert := assert.New(t)215assert.NoError(err)216assert.Equal(reflect.TypeOf(s).Elem().Name(), "storage")217assert.Equal(s.(*storage).maxSize, int64(config.DefaultStorageMaxSize*megabyte))218assert.Equal(s.(*storage).maxBackups, config.DefaultStorageMaxBackups)219assert.Equal(s.(*storage).bufferSize, config.DefaultStorageBufferSize)220
221assert.Equal(cap(s.(*storage).downloadBuffer), config.DefaultStorageBufferSize)222assert.Equal(len(s.(*storage).downloadBuffer), 0)223assert.Equal(s.(*storage).downloadCount, int64(0))224
225assert.Equal(cap(s.(*storage).networkTopologyBuffer), config.DefaultStorageBufferSize)226assert.Equal(len(s.(*storage).networkTopologyBuffer), 0)227assert.Equal(s.(*storage).networkTopologyCount, int64(0))228
229if err := s.ClearDownload(); err != nil {230t.Fatal(err)231}232
233if err := s.ClearNetworkTopology(); err != nil {234t.Fatal(err)235}236},237},238{239name: "new storage failed",240baseDir: "/foo",241expect: func(t *testing.T, s Storage, err error) {242assert := assert.New(t)243assert.Error(err)244},245},246}247
248for _, tc := range tests {249t.Run(tc.name, func(t *testing.T) {250s, err := New(tc.baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, config.DefaultStorageBufferSize)251tc.expect(t, s, err)252})253}254}
255
256func TestStorage_CreateDownload(t *testing.T) {257tests := []struct {258name string259baseDir string260bufferSize int261mock func(s Storage)262expect func(t *testing.T, s Storage, baseDir string)263}{264{265name: "create download",266baseDir: os.TempDir(),267bufferSize: 1,268mock: func(s Storage) {},269expect: func(t *testing.T, s Storage, baseDir string) {270assert := assert.New(t)271assert.NoError(s.CreateDownload(Download{}))272assert.Equal(s.(*storage).downloadCount, int64(0))273},274},275{276name: "create download without buffer",277baseDir: os.TempDir(),278bufferSize: 0,279mock: func(s Storage) {280},281expect: func(t *testing.T, s Storage, baseDir string) {282assert := assert.New(t)283assert.NoError(s.CreateDownload(Download{}))284assert.Equal(s.(*storage).downloadCount, int64(1))285
286downloads, err := s.ListDownload()287assert.NoError(err)288assert.Equal(len(downloads), 1)289},290},291{292name: "write download to file",293baseDir: os.TempDir(),294bufferSize: 1,295mock: func(s Storage) {296},297expect: func(t *testing.T, s Storage, baseDir string) {298assert := assert.New(t)299assert.NoError(s.CreateDownload(Download{}))300assert.NoError(s.CreateDownload(Download{}))301assert.Equal(s.(*storage).downloadCount, int64(1))302},303},304{305name: "open file failed",306baseDir: os.TempDir(),307bufferSize: 0,308mock: func(s Storage) {309s.(*storage).baseDir = "foo"310},311expect: func(t *testing.T, s Storage, baseDir string) {312assert := assert.New(t)313assert.Error(s.CreateDownload(Download{}))314s.(*storage).baseDir = baseDir315},316},317}318
319for _, tc := range tests {320t.Run(tc.name, func(t *testing.T) {321s, err := New(tc.baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, tc.bufferSize)322if err != nil {323t.Fatal(err)324}325
326tc.mock(s)327tc.expect(t, s, tc.baseDir)328if err := s.ClearDownload(); err != nil {329t.Fatal(err)330}331})332}333}
334
335func TestStorage_CreateNetworkTopology(t *testing.T) {336tests := []struct {337name string338baseDir string339bufferSize int340mock func(s Storage)341expect func(t *testing.T, s Storage, baseDir string)342}{343{344name: "create network topology",345baseDir: os.TempDir(),346bufferSize: 1,347mock: func(s Storage) {},348expect: func(t *testing.T, s Storage, baseDir string) {349assert := assert.New(t)350assert.NoError(s.CreateNetworkTopology(NetworkTopology{}))351assert.Equal(s.(*storage).networkTopologyCount, int64(0))352},353},354{355name: "create network topology without buffer",356baseDir: os.TempDir(),357bufferSize: 0,358mock: func(s Storage) {359},360expect: func(t *testing.T, s Storage, baseDir string) {361assert := assert.New(t)362assert.NoError(s.CreateNetworkTopology(NetworkTopology{}))363assert.Equal(s.(*storage).networkTopologyCount, int64(1))364
365networkTopologies, err := s.ListNetworkTopology()366assert.NoError(err)367assert.Equal(len(networkTopologies), 1)368},369},370{371name: "write network topology to file",372baseDir: os.TempDir(),373bufferSize: 1,374mock: func(s Storage) {375},376expect: func(t *testing.T, s Storage, baseDir string) {377assert := assert.New(t)378assert.NoError(s.CreateNetworkTopology(NetworkTopology{}))379assert.NoError(s.CreateNetworkTopology(NetworkTopology{}))380assert.Equal(s.(*storage).networkTopologyCount, int64(1))381},382},383{384name: "open file failed",385baseDir: os.TempDir(),386bufferSize: 0,387mock: func(s Storage) {388s.(*storage).baseDir = "baw"389},390expect: func(t *testing.T, s Storage, baseDir string) {391assert := assert.New(t)392assert.Error(s.CreateNetworkTopology(NetworkTopology{}))393s.(*storage).baseDir = baseDir394},395},396}397
398for _, tc := range tests {399t.Run(tc.name, func(t *testing.T) {400s, err := New(tc.baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, tc.bufferSize)401if err != nil {402t.Fatal(err)403}404
405tc.mock(s)406tc.expect(t, s, tc.baseDir)407if err := s.ClearNetworkTopology(); err != nil {408t.Fatal(err)409}410})411}412}
413
414func TestStorage_ListDownload(t *testing.T) {415tests := []struct {416name string417baseDir string418bufferSize int419download Download
420mock func(t *testing.T, s Storage, baseDir string, download Download)421expect func(t *testing.T, s Storage, baseDir string, download Download)422}{423{424name: "empty csv file given",425baseDir: os.TempDir(),426bufferSize: config.DefaultStorageBufferSize,427mock: func(t *testing.T, s Storage, baseDir string, download Download) {},428expect: func(t *testing.T, s Storage, baseDir string, download Download) {429assert := assert.New(t)430_, err := s.ListDownload()431assert.Error(err)432},433},434{435name: "get file infos failed",436baseDir: os.TempDir(),437bufferSize: config.DefaultStorageBufferSize,438mock: func(t *testing.T, s Storage, baseDir string, download Download) {439s.(*storage).baseDir = "bae"440},441expect: func(t *testing.T, s Storage, baseDir string, download Download) {442assert := assert.New(t)443_, err := s.ListDownload()444assert.Error(err)445s.(*storage).baseDir = baseDir446},447},448{449name: "open file failed",450baseDir: os.TempDir(),451bufferSize: config.DefaultStorageBufferSize,452mock: func(t *testing.T, s Storage, baseDir string, download Download) {453file, err := os.OpenFile(filepath.Join(baseDir, "download_test.csv"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0300)454if err != nil {455t.Fatal(err)456}457file.Close()458},459expect: func(t *testing.T, s Storage, baseDir string, download Download) {460assert := assert.New(t)461_, err := s.ListDownload()462assert.Error(err)463},464},465{466name: "list downloads of a file",467baseDir: os.TempDir(),468bufferSize: 1,469download: mockDownload,470mock: func(t *testing.T, s Storage, baseDir string, download Download) {471if err := s.CreateDownload(download); err != nil {472t.Fatal(err)473}474},475expect: func(t *testing.T, s Storage, baseDir string, download Download) {476assert := assert.New(t)477_, err := s.ListDownload()478assert.Error(err)479
480if err := s.CreateDownload(download); err != nil {481t.Fatal(err)482}483downloads, err := s.ListDownload()484assert.NoError(err)485assert.Equal(len(downloads), 1)486assert.EqualValues(downloads[0].ID, download.ID)487assert.EqualValues(downloads[0].Tag, download.Tag)488assert.EqualValues(downloads[0].Application, download.Application)489assert.EqualValues(downloads[0].State, download.State)490assert.EqualValues(downloads[0].Error, download.Error)491assert.EqualValues(downloads[0].Cost, download.Cost)492assert.EqualValues(downloads[0].Task, download.Task)493assert.EqualValues(downloads[0].Host, download.Host)494assert.EqualValues(downloads[0].CreatedAt, download.CreatedAt)495assert.EqualValues(downloads[0].UpdatedAt, download.UpdatedAt)496},497},498{499name: "list downloads of multi files",500baseDir: os.TempDir(),501bufferSize: 1,502download: Download{},503mock: func(t *testing.T, s Storage, baseDir string, download Download) {504if err := s.CreateDownload(Download{ID: "2"}); err != nil {505t.Fatal(err)506}507
508if err := s.CreateDownload(Download{ID: "1"}); err != nil {509t.Fatal(err)510}511
512if err := s.CreateDownload(Download{ID: "3"}); err != nil {513t.Fatal(err)514}515},516expect: func(t *testing.T, s Storage, baseDir string, download Download) {517assert := assert.New(t)518downloads, err := s.ListDownload()519assert.NoError(err)520assert.Equal(len(downloads), 2)521assert.Equal(downloads[0].ID, "2")522assert.Equal(downloads[1].ID, "1")523},524},525}526
527for _, tc := range tests {528t.Run(tc.name, func(t *testing.T) {529s, err := New(tc.baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, tc.bufferSize)530if err != nil {531t.Fatal(err)532}533
534tc.mock(t, s, tc.baseDir, tc.download)535tc.expect(t, s, tc.baseDir, tc.download)536if err := s.ClearDownload(); err != nil {537t.Fatal(err)538}539})540}541}
542
543func TestStorage_ListNetworkTopology(t *testing.T) {544tests := []struct {545name string546baseDir string547bufferSize int548networkTopology NetworkTopology
549mock func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology)550expect func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology)551}{552{553name: "empty csv file given",554baseDir: os.TempDir(),555bufferSize: config.DefaultStorageBufferSize,556mock: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {},557expect: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {558assert := assert.New(t)559_, err := s.ListNetworkTopology()560assert.Error(err)561},562},563{564name: "get file infos failed",565baseDir: os.TempDir(),566bufferSize: config.DefaultStorageBufferSize,567mock: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {568s.(*storage).baseDir = "bae"569},570expect: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {571assert := assert.New(t)572_, err := s.ListNetworkTopology()573assert.Error(err)574s.(*storage).baseDir = baseDir575},576},577{578name: "open file failed",579baseDir: os.TempDir(),580bufferSize: config.DefaultStorageBufferSize,581mock: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {582file, err := os.OpenFile(filepath.Join(baseDir, "networktopology_test.csv"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0300)583if err != nil {584t.Fatal(err)585}586file.Close()587},588expect: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {589assert := assert.New(t)590_, err := s.ListNetworkTopology()591assert.Error(err)592},593},594{595name: "list network topologies of a file",596baseDir: os.TempDir(),597bufferSize: 1,598networkTopology: mockNetworkTopology,599mock: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {600if err := s.CreateNetworkTopology(networkTopology); err != nil {601t.Fatal(err)602}603},604expect: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {605assert := assert.New(t)606_, err := s.ListNetworkTopology()607assert.Error(err)608
609if err := s.CreateNetworkTopology(networkTopology); err != nil {610t.Fatal(err)611}612networkTopologies, err := s.ListNetworkTopology()613assert.NoError(err)614assert.Equal(len(networkTopologies), 1)615assert.EqualValues(networkTopologies[0], networkTopology)616},617},618{619name: "list network topologies of multi files",620baseDir: os.TempDir(),621bufferSize: 1,622networkTopology: NetworkTopology{},623mock: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {624if err := s.CreateNetworkTopology(NetworkTopology{ID: "2"}); err != nil {625t.Fatal(err)626}627
628if err := s.CreateNetworkTopology(NetworkTopology{ID: "1"}); err != nil {629t.Fatal(err)630}631
632if err := s.CreateNetworkTopology(NetworkTopology{ID: "3"}); err != nil {633t.Fatal(err)634}635},636expect: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {637assert := assert.New(t)638networkTopologies, err := s.ListNetworkTopology()639assert.NoError(err)640assert.Equal(len(networkTopologies), 2)641assert.Equal(networkTopologies[0].ID, "2")642assert.Equal(networkTopologies[1].ID, "1")643},644},645}646
647for _, tc := range tests {648t.Run(tc.name, func(t *testing.T) {649s, err := New(tc.baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, tc.bufferSize)650if err != nil {651t.Fatal(err)652}653
654tc.mock(t, s, tc.baseDir, tc.networkTopology)655tc.expect(t, s, tc.baseDir, tc.networkTopology)656if err := s.ClearNetworkTopology(); err != nil {657t.Fatal(err)658}659})660}661}
662
663func TestStorage_DownloadCount(t *testing.T) {664tests := []struct {665name string666baseDir string667mock func(s Storage)668expect func(t *testing.T, s Storage)669}{670{671name: "get the count of downloads",672baseDir: os.TempDir(),673mock: func(s Storage) {674s.(*storage).downloadCount = 2675},676expect: func(t *testing.T, s Storage) {677assert := assert.New(t)678assert.Equal(int64(2), s.DownloadCount())679},680},681}682
683for _, tc := range tests {684t.Run(tc.name, func(t *testing.T) {685s, err := New(tc.baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, config.DefaultStorageBufferSize)686if err != nil {687t.Fatal(err)688}689
690tc.mock(s)691tc.expect(t, s)692})693}694}
695
696func TestStorage_NetworkTopologyCount(t *testing.T) {697tests := []struct {698name string699baseDir string700mock func(s Storage)701expect func(t *testing.T, s Storage)702}{703{704name: "get the count of network topologies",705baseDir: os.TempDir(),706mock: func(s Storage) {707s.(*storage).networkTopologyCount = 1708},709expect: func(t *testing.T, s Storage) {710assert := assert.New(t)711assert.Equal(int64(1), s.NetworkTopologyCount())712},713},714}715for _, tc := range tests {716t.Run(tc.name, func(t *testing.T) {717s, err := New(tc.baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, config.DefaultStorageBufferSize)718if err != nil {719t.Fatal(err)720}721
722tc.mock(s)723tc.expect(t, s)724})725}726}
727
728func TestStorage_OpenDownload(t *testing.T) {729tests := []struct {730name string731baseDir string732bufferSize int733download Download
734mock func(t *testing.T, s Storage, baseDir string, download Download)735expect func(t *testing.T, s Storage, baseDir string, download Download)736}{737{738name: "open storage withempty csv file given",739baseDir: os.TempDir(),740bufferSize: config.DefaultStorageBufferSize,741mock: func(t *testing.T, s Storage, baseDir string, download Download) {},742expect: func(t *testing.T, s Storage, baseDir string, download Download) {743assert := assert.New(t)744_, err := s.OpenDownload()745assert.NoError(err)746},747},748{749name: "open file infos failed",750baseDir: os.TempDir(),751bufferSize: config.DefaultStorageBufferSize,752mock: func(t *testing.T, s Storage, baseDir string, download Download) {753s.(*storage).baseDir = "bas"754},755expect: func(t *testing.T, s Storage, baseDir string, download Download) {756assert := assert.New(t)757_, err := s.OpenDownload()758assert.Error(err)759s.(*storage).baseDir = baseDir760},761},762{763name: "open storage with downloads of a file",764baseDir: os.TempDir(),765bufferSize: 1,766download: mockDownload,767mock: func(t *testing.T, s Storage, baseDir string, download Download) {768if err := s.CreateDownload(download); err != nil {769t.Fatal(err)770}771},772expect: func(t *testing.T, s Storage, baseDir string, download Download) {773assert := assert.New(t)774_, err := s.OpenDownload()775assert.NoError(err)776
777if err := s.CreateDownload(download); err != nil {778t.Fatal(err)779}780
781readCloser, err := s.OpenDownload()782assert.NoError(err)783
784var downloads []Download785err = gocsv.UnmarshalWithoutHeaders(readCloser, &downloads)786assert.NoError(err)787assert.Equal(len(downloads), 1)788assert.EqualValues(downloads[0].ID, download.ID)789assert.EqualValues(downloads[0].Tag, download.Tag)790assert.EqualValues(downloads[0].Application, download.Application)791assert.EqualValues(downloads[0].State, download.State)792assert.EqualValues(downloads[0].Error, download.Error)793assert.EqualValues(downloads[0].Cost, download.Cost)794assert.EqualValues(downloads[0].Task, download.Task)795assert.EqualValues(downloads[0].Host, download.Host)796assert.EqualValues(downloads[0].CreatedAt, download.CreatedAt)797assert.EqualValues(downloads[0].UpdatedAt, download.UpdatedAt)798},799},800{801name: "open storage with downloads of multi files",802baseDir: os.TempDir(),803bufferSize: 1,804download: Download{},805mock: func(t *testing.T, s Storage, baseDir string, download Download) {806if err := s.CreateDownload(Download{ID: "2"}); err != nil {807t.Fatal(err)808}809
810if err := s.CreateDownload(Download{ID: "1"}); err != nil {811t.Fatal(err)812}813
814if err := s.CreateDownload(Download{ID: "3"}); err != nil {815t.Fatal(err)816}817},818expect: func(t *testing.T, s Storage, baseDir string, download Download) {819assert := assert.New(t)820readCloser, err := s.OpenDownload()821assert.NoError(err)822
823var downloads []Download824err = gocsv.UnmarshalWithoutHeaders(readCloser, &downloads)825assert.NoError(err)826assert.Equal(len(downloads), 2)827assert.Equal(downloads[0].ID, "2")828assert.Equal(downloads[1].ID, "1")829},830},831}832
833for _, tc := range tests {834t.Run(tc.name, func(t *testing.T) {835s, err := New(tc.baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, tc.bufferSize)836if err != nil {837t.Fatal(err)838}839
840tc.mock(t, s, tc.baseDir, tc.download)841tc.expect(t, s, tc.baseDir, tc.download)842if err := s.ClearDownload(); err != nil {843t.Fatal(err)844}845})846}847}
848
849func TestStorage_OpenNetworkTopology(t *testing.T) {850tests := []struct {851name string852baseDir string853bufferSize int854networkTopology NetworkTopology
855mock func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology)856expect func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology)857}{858{859name: "open storage with empty csv file given",860baseDir: os.TempDir(),861bufferSize: config.DefaultStorageBufferSize,862mock: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {},863expect: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {864assert := assert.New(t)865_, err := s.OpenNetworkTopology()866assert.NoError(err)867},868},869{870name: "open file infos failed",871baseDir: os.TempDir(),872bufferSize: config.DefaultStorageBufferSize,873mock: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {874s.(*storage).baseDir = "bas"875},876expect: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {877assert := assert.New(t)878_, err := s.OpenNetworkTopology()879assert.Error(err)880s.(*storage).baseDir = baseDir881},882},883{884name: "open storage with network topologies of a file",885baseDir: os.TempDir(),886bufferSize: 1,887networkTopology: mockNetworkTopology,888mock: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {889if err := s.CreateNetworkTopology(networkTopology); err != nil {890t.Fatal(err)891}892},893expect: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {894assert := assert.New(t)895_, err := s.OpenNetworkTopology()896assert.NoError(err)897
898if err := s.CreateNetworkTopology(networkTopology); err != nil {899t.Fatal(err)900}901
902readCloser, err := s.OpenNetworkTopology()903assert.NoError(err)904
905var networkTopologies []NetworkTopology906err = gocsv.UnmarshalWithoutHeaders(readCloser, &networkTopologies)907assert.NoError(err)908assert.Equal(len(networkTopologies), 1)909assert.EqualValues(networkTopologies[0], networkTopology)910},911},912{913name: "open storage with network topologies of multi files",914baseDir: os.TempDir(),915bufferSize: 1,916networkTopology: NetworkTopology{},917mock: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {918if err := s.CreateNetworkTopology(NetworkTopology{ID: "2"}); err != nil {919t.Fatal(err)920}921
922if err := s.CreateNetworkTopology(NetworkTopology{ID: "1"}); err != nil {923t.Fatal(err)924}925
926if err := s.CreateNetworkTopology(NetworkTopology{ID: "3"}); err != nil {927t.Fatal(err)928}929},930expect: func(t *testing.T, s Storage, baseDir string, networkTopology NetworkTopology) {931assert := assert.New(t)932readCloser, err := s.OpenNetworkTopology()933assert.NoError(err)934
935var networkTopologies []NetworkTopology936err = gocsv.UnmarshalWithoutHeaders(readCloser, &networkTopologies)937assert.NoError(err)938assert.Equal(len(networkTopologies), 2)939assert.Equal(networkTopologies[0].ID, "2")940assert.Equal(networkTopologies[1].ID, "1")941},942},943}944
945for _, tc := range tests {946t.Run(tc.name, func(t *testing.T) {947s, err := New(tc.baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, tc.bufferSize)948if err != nil {949t.Fatal(err)950}951
952tc.mock(t, s, tc.baseDir, tc.networkTopology)953tc.expect(t, s, tc.baseDir, tc.networkTopology)954if err := s.ClearNetworkTopology(); err != nil {955t.Fatal(err)956}957})958}959}
960
961func TestStorage_ClearDownload(t *testing.T) {962tests := []struct {963name string964baseDir string965mock func(s Storage)966expect func(t *testing.T, s Storage, baseDir string)967}{968{969name: "clear file",970baseDir: os.TempDir(),971mock: func(s Storage) {},972expect: func(t *testing.T, s Storage, baseDir string) {973assert := assert.New(t)974assert.NoError(s.ClearDownload())975fileInfos, err := os.ReadDir(filepath.Join(baseDir))976assert.NoError(err)977
978var backups []os.DirEntry979regexp := regexp.MustCompile(DownloadFilePrefix)980for _, fileInfo := range fileInfos {981if !fileInfo.IsDir() && regexp.MatchString(fileInfo.Name()) {982backups = append(backups, fileInfo)983}984}985assert.Equal(len(backups), 0)986},987},988{989name: "open file failed",990baseDir: os.TempDir(),991mock: func(s Storage) {992s.(*storage).baseDir = "baz"993},994expect: func(t *testing.T, s Storage, baseDir string) {995assert := assert.New(t)996assert.Error(s.ClearDownload())997
998s.(*storage).baseDir = baseDir999assert.NoError(s.ClearDownload())1000},1001},1002}1003
1004for _, tc := range tests {1005t.Run(tc.name, func(t *testing.T) {1006s, err := New(tc.baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, config.DefaultStorageBufferSize)1007if err != nil {1008t.Fatal(err)1009}1010
1011tc.mock(s)1012tc.expect(t, s, tc.baseDir)1013})1014}1015}
1016
1017func TestStorage_ClearNetworkTopology(t *testing.T) {1018tests := []struct {1019name string1020baseDir string1021mock func(s Storage)1022expect func(t *testing.T, s Storage, baseDir string)1023}{1024{1025name: "clear file",1026baseDir: os.TempDir(),1027mock: func(s Storage) {},1028expect: func(t *testing.T, s Storage, baseDir string) {1029assert := assert.New(t)1030assert.NoError(s.ClearNetworkTopology())1031fileInfos, err := os.ReadDir(filepath.Join(baseDir))1032assert.NoError(err)1033
1034var backups []fs.FileInfo1035regexp := regexp.MustCompile(NetworkTopologyFilePrefix)1036for _, fileInfo := range fileInfos {1037if !fileInfo.IsDir() && regexp.MatchString(fileInfo.Name()) {1038info, _ := fileInfo.Info()1039backups = append(backups, info)1040}1041}1042assert.Equal(len(backups), 0)1043},1044},1045{1046name: "open file failed",1047baseDir: os.TempDir(),1048mock: func(s Storage) {1049s.(*storage).baseDir = "baz"1050},1051expect: func(t *testing.T, s Storage, baseDir string) {1052assert := assert.New(t)1053assert.Error(s.ClearNetworkTopology())1054
1055s.(*storage).baseDir = baseDir1056assert.NoError(s.ClearNetworkTopology())1057},1058},1059}1060
1061for _, tc := range tests {1062t.Run(tc.name, func(t *testing.T) {1063s, err := New(tc.baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, config.DefaultStorageBufferSize)1064if err != nil {1065t.Fatal(err)1066}1067
1068tc.mock(s)1069tc.expect(t, s, tc.baseDir)1070})1071}1072}
1073
1074func TestStorage_createDownload(t *testing.T) {1075tests := []struct {1076name string1077baseDir string1078mock func(s Storage)1079expect func(t *testing.T, s Storage, baseDir string)1080}{1081{1082name: "create download",1083baseDir: os.TempDir(),1084mock: func(s Storage) {},1085expect: func(t *testing.T, s Storage, baseDir string) {1086assert := assert.New(t)1087assert.NoError(s.(*storage).createDownload(Download{}))1088},1089},1090{1091name: "open file failed",1092baseDir: os.TempDir(),1093mock: func(s Storage) {1094s.(*storage).baseDir = "foo"1095},1096expect: func(t *testing.T, s Storage, baseDir string) {1097assert := assert.New(t)1098assert.Error(s.(*storage).createDownload(Download{}))1099s.(*storage).baseDir = baseDir1100},1101},1102}1103
1104for _, tc := range tests {1105t.Run(tc.name, func(t *testing.T) {1106s, err := New(tc.baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, config.DefaultStorageBufferSize)1107if err != nil {1108t.Fatal(err)1109}1110
1111tc.mock(s)1112tc.expect(t, s, tc.baseDir)1113if err := s.ClearDownload(); err != nil {1114t.Fatal(err)1115}1116})1117}1118}
1119
1120func TestStorage_createNetworkTopology(t *testing.T) {1121tests := []struct {1122name string1123baseDir string1124mock func(s Storage)1125expect func(t *testing.T, s Storage, baseDir string)1126}{1127{1128name: "create network topology",1129baseDir: os.TempDir(),1130mock: func(s Storage) {},1131expect: func(t *testing.T, s Storage, baseDir string) {1132assert := assert.New(t)1133assert.NoError(s.(*storage).createNetworkTopology(NetworkTopology{}))1134},1135},1136{1137name: "open file failed",1138baseDir: os.TempDir(),1139mock: func(s Storage) {1140s.(*storage).baseDir = "baw"1141},1142expect: func(t *testing.T, s Storage, baseDir string) {1143assert := assert.New(t)1144assert.Error(s.(*storage).createNetworkTopology(NetworkTopology{}))1145s.(*storage).baseDir = baseDir1146},1147},1148}1149
1150for _, tc := range tests {1151t.Run(tc.name, func(t *testing.T) {1152s, err := New(tc.baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, config.DefaultStorageBufferSize)1153if err != nil {1154t.Fatal(err)1155}1156
1157tc.mock(s)1158tc.expect(t, s, tc.baseDir)1159if err := s.ClearNetworkTopology(); err != nil {1160t.Fatal(err)1161}1162})1163}1164}
1165
1166func TestStorage_openDownloadFile(t *testing.T) {1167tests := []struct {1168name string1169baseDir string1170maxSize int1171maxBackups int1172
1173bufferSize int1174mock func(t *testing.T, s Storage)1175expect func(t *testing.T, s Storage, baseDir string)1176}{1177{1178name: "open file failed",1179baseDir: os.TempDir(),1180maxSize: config.DefaultStorageMaxSize,1181maxBackups: config.DefaultStorageMaxBackups,1182bufferSize: config.DefaultStorageBufferSize,1183mock: func(t *testing.T, s Storage) {1184s.(*storage).baseDir = "bat"1185},1186expect: func(t *testing.T, s Storage, baseDir string) {1187assert := assert.New(t)1188_, err := s.(*storage).openDownloadFile()1189assert.Error(err)1190s.(*storage).baseDir = baseDir1191},1192},1193{1194name: "open new download file",1195baseDir: os.TempDir(),1196maxSize: 0,1197maxBackups: config.DefaultStorageMaxBackups,1198bufferSize: 1,1199mock: func(t *testing.T, s Storage) {1200if err := s.CreateDownload(Download{ID: "1"}); err != nil {1201t.Fatal(err)1202}1203
1204if err := s.CreateDownload(Download{ID: "2"}); err != nil {1205t.Fatal(err)1206}1207},1208expect: func(t *testing.T, s Storage, baseDir string) {1209assert := assert.New(t)1210file, err := s.(*storage).openDownloadFile()1211assert.NoError(err)1212assert.Equal(file.Name(), filepath.Join(baseDir, fmt.Sprintf("%s.%s", DownloadFilePrefix, CSVFileExt)))1213file.Close()1214},1215},1216{1217name: "remove download file",1218baseDir: os.TempDir(),1219maxSize: 0,1220maxBackups: 1,1221bufferSize: 1,1222mock: func(t *testing.T, s Storage) {1223if err := s.CreateDownload(Download{ID: "1"}); err != nil {1224t.Fatal(err)1225}1226},1227expect: func(t *testing.T, s Storage, baseDir string) {1228assert := assert.New(t)1229file, err := s.(*storage).openDownloadFile()1230assert.NoError(err)1231assert.Equal(file.Name(), filepath.Join(baseDir, fmt.Sprintf("%s.%s", DownloadFilePrefix, CSVFileExt)))1232file.Close()1233},1234},1235}1236
1237for _, tc := range tests {1238t.Run(tc.name, func(t *testing.T) {1239s, err := New(tc.baseDir, tc.maxSize, tc.maxBackups, tc.bufferSize)1240if err != nil {1241t.Fatal(err)1242}1243
1244tc.mock(t, s)1245tc.expect(t, s, tc.baseDir)1246if err := s.ClearDownload(); err != nil {1247t.Fatal(err)1248}1249})1250}1251}
1252
1253func TestStorage_openNetworkTopologyFile(t *testing.T) {1254tests := []struct {1255name string1256baseDir string1257maxSize int1258maxBackups int1259
1260bufferSize int1261mock func(t *testing.T, s Storage)1262expect func(t *testing.T, s Storage, baseDir string)1263}{1264{1265name: "open file failed",1266baseDir: os.TempDir(),1267maxSize: config.DefaultStorageMaxSize,1268maxBackups: config.DefaultStorageMaxBackups,1269bufferSize: config.DefaultStorageBufferSize,1270mock: func(t *testing.T, s Storage) {1271s.(*storage).baseDir = "bat"1272},1273expect: func(t *testing.T, s Storage, baseDir string) {1274assert := assert.New(t)1275_, err := s.(*storage).openNetworkTopologyFile()1276assert.Error(err)1277s.(*storage).baseDir = baseDir1278},1279},1280{1281name: "open new network topology file",1282baseDir: os.TempDir(),1283maxSize: 0,1284maxBackups: config.DefaultStorageMaxBackups,1285bufferSize: 1,1286mock: func(t *testing.T, s Storage) {1287if err := s.CreateNetworkTopology(NetworkTopology{ID: "1"}); err != nil {1288t.Fatal(err)1289}1290
1291if err := s.CreateNetworkTopology(NetworkTopology{ID: "2"}); err != nil {1292t.Fatal(err)1293}1294},1295expect: func(t *testing.T, s Storage, baseDir string) {1296assert := assert.New(t)1297file, err := s.(*storage).openNetworkTopologyFile()1298assert.NoError(err)1299assert.Equal(file.Name(), filepath.Join(baseDir, fmt.Sprintf("%s.%s", NetworkTopologyFilePrefix, CSVFileExt)))1300file.Close()1301},1302},1303{1304name: "remove network topology file",1305baseDir: os.TempDir(),1306maxSize: 0,1307maxBackups: 1,1308bufferSize: 1,1309mock: func(t *testing.T, s Storage) {1310if err := s.CreateNetworkTopology(NetworkTopology{ID: "1"}); err != nil {1311t.Fatal(err)1312}1313},1314expect: func(t *testing.T, s Storage, baseDir string) {1315assert := assert.New(t)1316file, err := s.(*storage).openNetworkTopologyFile()1317assert.NoError(err)1318assert.Equal(file.Name(), filepath.Join(baseDir, fmt.Sprintf("%s.%s", NetworkTopologyFilePrefix, CSVFileExt)))1319file.Close()1320},1321},1322}1323
1324for _, tc := range tests {1325t.Run(tc.name, func(t *testing.T) {1326s, err := New(tc.baseDir, tc.maxSize, tc.maxBackups, tc.bufferSize)1327if err != nil {1328t.Fatal(err)1329}1330
1331tc.mock(t, s)1332tc.expect(t, s, tc.baseDir)1333if err := s.ClearNetworkTopology(); err != nil {1334t.Fatal(err)1335}1336})1337}1338}
1339
1340func TestStorage_downloadBackupFilename(t *testing.T) {1341baseDir := os.TempDir()1342s, err := New(baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, config.DefaultStorageBufferSize)1343if err != nil {1344t.Fatal(err)1345}1346
1347filename := s.(*storage).downloadBackupFilename()1348regexp := regexp.MustCompile(fmt.Sprintf("%s_.*.%s$", DownloadFilePrefix, CSVFileExt))1349assert := assert.New(t)1350assert.True(regexp.MatchString(filename))1351
1352if err := s.ClearDownload(); err != nil {1353t.Fatal(err)1354}1355}
1356
1357func TestStorage_networkTopologyBackupFilename(t *testing.T) {1358baseDir := os.TempDir()1359s, err := New(baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, config.DefaultStorageBufferSize)1360if err != nil {1361t.Fatal(err)1362}1363
1364filename := s.(*storage).networkTopologyBackupFilename()1365regexp := regexp.MustCompile(fmt.Sprintf("%s_.*.%s$", NetworkTopologyFilePrefix, CSVFileExt))1366assert := assert.New(t)1367assert.True(regexp.MatchString(filename))1368
1369if err := s.ClearNetworkTopology(); err != nil {1370t.Fatal(err)1371}1372}
1373
1374func TestStorage_downloadBackups(t *testing.T) {1375tests := []struct {1376name string1377baseDir string1378mock func(t *testing.T, s Storage)1379expect func(t *testing.T, s Storage, baseDir string)1380}{1381{1382name: "open file failed",1383baseDir: os.TempDir(),1384mock: func(t *testing.T, s Storage) {1385s.(*storage).baseDir = "bar"1386},1387expect: func(t *testing.T, s Storage, baseDir string) {1388assert := assert.New(t)1389_, err := s.(*storage).downloadBackups()1390assert.Error(err)1391s.(*storage).baseDir = baseDir1392if err := s.ClearDownload(); err != nil {1393t.Fatal(err)1394}1395},1396},1397{1398name: "not found download file",1399baseDir: os.TempDir(),1400mock: func(t *testing.T, s Storage) {},1401expect: func(t *testing.T, s Storage, baseDir string) {1402assert := assert.New(t)1403if err := s.ClearDownload(); err != nil {1404t.Fatal(err)1405}1406
1407_, err := s.(*storage).downloadBackups()1408assert.Error(err)1409},1410},1411}1412
1413for _, tc := range tests {1414t.Run(tc.name, func(t *testing.T) {1415s, err := New(tc.baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, config.DefaultStorageBufferSize)1416if err != nil {1417t.Fatal(err)1418}1419
1420tc.mock(t, s)1421tc.expect(t, s, tc.baseDir)1422})1423}1424}
1425
1426func TestStorage_networkTopologyBackups(t *testing.T) {1427tests := []struct {1428name string1429baseDir string1430mock func(t *testing.T, s Storage)1431expect func(t *testing.T, s Storage, baseDir string)1432}{1433{1434name: "open file failed",1435baseDir: os.TempDir(),1436mock: func(t *testing.T, s Storage) {1437s.(*storage).baseDir = "bar"1438},1439expect: func(t *testing.T, s Storage, baseDir string) {1440assert := assert.New(t)1441_, err := s.(*storage).networkTopologyBackups()1442assert.Error(err)1443s.(*storage).baseDir = baseDir1444if err := s.ClearNetworkTopology(); err != nil {1445t.Fatal(err)1446}1447},1448},1449{1450name: "not found network topology file",1451baseDir: os.TempDir(),1452mock: func(t *testing.T, s Storage) {},1453expect: func(t *testing.T, s Storage, baseDir string) {1454assert := assert.New(t)1455if err := s.ClearNetworkTopology(); err != nil {1456t.Fatal(err)1457}1458
1459_, err := s.(*storage).networkTopologyBackups()1460assert.Error(err)1461},1462},1463}1464
1465for _, tc := range tests {1466t.Run(tc.name, func(t *testing.T) {1467s, err := New(tc.baseDir, config.DefaultStorageMaxSize, config.DefaultStorageMaxBackups, config.DefaultStorageBufferSize)1468if err != nil {1469t.Fatal(err)1470}1471
1472tc.mock(t, s)1473tc.expect(t, s, tc.baseDir)1474})1475}1476}
1477