diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c129a827..2e913f0ba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ env: VALIDATOR_REGISTRY: ${{ secrets.VALIDATOR_REGISTRY }} jobs: - build: + test: runs-on: ubuntu-20.04 steps: - name: Install Go @@ -25,22 +25,15 @@ jobs: - uses: satackey/action-docker-layer-caching@v0.0.11 # Ignore the failure of a step and avoid terminating the job. continue-on-error: true - - name: Build + - name: Build test environment and run tests run: | + ./docker.local/bin/blobber.init.setup.sh docker network create --driver=bridge --subnet=198.18.0.0/15 --gateway=198.18.0.255 testnet0 ./docker.local/bin/build.blobber.sh - - test: - runs-on: ubuntu-20.04 - steps: - - name: Install Go - uses: actions/setup-go@v2 - with: - go-version: 1.14.x - - uses: actions/checkout@v2 - - name: Test - run: make test - + cd docker.local/blobber1 + ../bin/blobber.start_bls.sh /dev/null & + cd ../.. + make integration-tests lint: runs-on: ubuntu-20.04 steps: diff --git a/Makefile b/Makefile index 0db3a71d0..ef5d2f84d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,10 @@ -.PHONY: test lint +.PHONY: test lint integration-tests test: go test ./...; lint: - golangci-lint run; \ No newline at end of file + golangci-lint run; + +integration-tests: + go test ./... -args integration; \ No newline at end of file diff --git a/code/go/0chain.net/blobber/main.go b/code/go/0chain.net/blobber/main.go index 4a59f5da7..cb26ee6eb 100644 --- a/code/go/0chain.net/blobber/main.go +++ b/code/go/0chain.net/blobber/main.go @@ -227,7 +227,7 @@ func main() { flag.Parse() config.SetupDefaultConfig() - config.SetupConfig() + config.SetupConfig("./config") config.Configuration.DeploymentMode = byte(*deploymentMode) @@ -339,10 +339,11 @@ func main() { methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"}) + common.ConfigRateLimits() initHandlers(r) initServer() - grpcServer := handler.NewServerWithMiddlewares(common.ConfigRateLimits()) + grpcServer := handler.NewServerWithMiddlewares(common.NewGRPCRateLimiter()) handler.RegisterGRPCServices(r, grpcServer) rHandler := handlers.CORS(originsOk, headersOk, methodsOk)(r) diff --git a/code/go/0chain.net/blobbercore/config/config.go b/code/go/0chain.net/blobbercore/config/config.go index 27c4fdc6d..bb79c507e 100644 --- a/code/go/0chain.net/blobbercore/config/config.go +++ b/code/go/0chain.net/blobbercore/config/config.go @@ -44,12 +44,12 @@ func SetupDefaultConfig() { } /*SetupConfig - setup the configuration system */ -func SetupConfig() { +func SetupConfig(configPath string) { replacer := strings.NewReplacer(".", "_") viper.SetEnvKeyReplacer(replacer) viper.AutomaticEnv() viper.SetConfigName("0chain_blobber") - viper.AddConfigPath("./config") + viper.AddConfigPath(configPath) err := viper.ReadInConfig() // Find and read the config file if err != nil { // Handle errors reading the config file panic(fmt.Errorf("fatal error config file: %s", err)) diff --git a/code/go/0chain.net/blobbercore/handler/grpc_handler_helper_unit_test.go b/code/go/0chain.net/blobbercore/handler/grpc_handler_helper_unit_test.go index e85275174..0b286f5e1 100644 --- a/code/go/0chain.net/blobbercore/handler/grpc_handler_helper_unit_test.go +++ b/code/go/0chain.net/blobbercore/handler/grpc_handler_helper_unit_test.go @@ -2,10 +2,20 @@ package handler import ( "context" - "testing" + "database/sql" + "fmt" + "log" + "os" + "strings" + "time" "github.com/0chain/blobber/code/go/0chain.net/blobbercore/config" - coreConfig "github.com/0chain/blobber/code/go/0chain.net/core/config" + "github.com/spf13/viper" + + "testing" + + "gorm.io/gorm" + "github.com/0chain/gosdk/core/zcncrypto" "github.com/0chain/blobber/code/go/0chain.net/blobbercore/allocation" @@ -62,10 +72,412 @@ func (_m *storageHandlerI) verifyAuthTicket(ctx context.Context, authTokenString return r0, r1 } +type TestDataController struct { + db *gorm.DB +} + +func NewTestDataController(db *gorm.DB) *TestDataController { + return &TestDataController{db: db} +} + +// ClearDatabase deletes all data from all tables +func (c *TestDataController) ClearDatabase() error { + var err error + var tx *sql.Tx + defer func() { + if err != nil { + if tx != nil { + errRollback := tx.Rollback() + if errRollback != nil { + log.Println(errRollback) + } + } + } + }() + + db, err := c.db.DB() + if err != nil { + return err + } + + tx, err = db.BeginTx(context.Background(), &sql.TxOptions{}) + if err != nil { + return err + } + + _, err = tx.Exec("truncate allocations cascade") + if err != nil { + return err + } + + _, err = tx.Exec("truncate reference_objects cascade") + if err != nil { + return err + } + + _, err = tx.Exec("truncate commit_meta_txns cascade") + if err != nil { + return err + } + + _, err = tx.Exec("truncate collaborators cascade") + if err != nil { + return err + } + + err = tx.Commit() + if err != nil { + return err + } + + return nil +} + +func (c *TestDataController) AddGetAllocationTestData() error { + var err error + var tx *sql.Tx + defer func() { + if err != nil { + if tx != nil { + errRollback := tx.Rollback() + if errRollback != nil { + log.Println(errRollback) + } + } + } + }() + + db, err := c.db.DB() + if err != nil { + return err + } + + tx, err = db.BeginTx(context.Background(), &sql.TxOptions{}) + if err != nil { + return err + } + + expTime := time.Now().Add(time.Hour * 100000).UnixNano() + + _, err = tx.Exec(` +INSERT INTO allocations (id, tx, owner_id, owner_public_key, expiration_date, payer_id) +VALUES ('exampleId' ,'exampleTransaction','exampleOwnerId','exampleOwnerPublicKey',` + fmt.Sprint(expTime) + `,'examplePayerId'); +`) + if err != nil { + return err + } + + err = tx.Commit() + if err != nil { + return err + } + + return nil +} + +func (c *TestDataController) AddGetFileMetaDataTestData() error { + var err error + var tx *sql.Tx + defer func() { + if err != nil { + if tx != nil { + errRollback := tx.Rollback() + if errRollback != nil { + log.Println(errRollback) + } + } + } + }() + + db, err := c.db.DB() + if err != nil { + return err + } + + tx, err = db.BeginTx(context.Background(), &sql.TxOptions{}) + if err != nil { + return err + } + + expTime := time.Now().Add(time.Hour * 100000).UnixNano() + + _, err = tx.Exec(` +INSERT INTO allocations (id, tx, owner_id, owner_public_key, expiration_date, payer_id) +VALUES ('exampleId' ,'exampleTransaction','exampleOwnerId','exampleOwnerPublicKey',` + fmt.Sprint(expTime) + `,'examplePayerId'); +`) + if err != nil { + return err + } + + _, err = tx.Exec(` +INSERT INTO reference_objects (id, allocation_id, path_hash,lookup_hash,type,name,path,hash,custom_meta,content_hash,merkle_root,actual_file_hash,mimetype,write_marker,thumbnail_hash, actual_thumbnail_hash) +VALUES (1234,'exampleId','exampleId:examplePath','exampleId:examplePath','f','filename','examplePath','someHash','customMeta','contentHash','merkleRoot','actualFileHash','mimetype','writeMarker','thumbnailHash','actualThumbnailHash'); +`) + if err != nil { + return err + } + + _, err = tx.Exec(` +INSERT INTO commit_meta_txns (ref_id,txn_id) +VALUES (1234,'someTxn'); +`) + if err != nil { + return err + } + + _, err = tx.Exec(` +INSERT INTO collaborators (ref_id, client_id) +VALUES (1234, 'someClient'); +`) + if err != nil { + return err + } + + err = tx.Commit() + if err != nil { + return err + } + + return nil +} + +func (c *TestDataController) AddGetFileStatsTestData(allocationTx, pubKey string) error { + var err error + var tx *sql.Tx + defer func() { + if err != nil { + if tx != nil { + errRollback := tx.Rollback() + if errRollback != nil { + log.Println(errRollback) + } + } + } + }() + + db, err := c.db.DB() + if err != nil { + return err + } + + tx, err = db.BeginTx(context.Background(), &sql.TxOptions{}) + if err != nil { + return err + } + + expTime := time.Now().Add(time.Hour * 100000).UnixNano() + + _, err = tx.Exec(` +INSERT INTO allocations (id, tx, owner_id, owner_public_key, expiration_date, payer_id) +VALUES ('exampleId' ,'` + allocationTx + `','exampleOwnerId','` + pubKey + `',` + fmt.Sprint(expTime) + `,'examplePayerId'); +`) + if err != nil { + return err + } + + _, err = tx.Exec(` +INSERT INTO reference_objects (id, allocation_id, path_hash,lookup_hash,type,name,path,hash,custom_meta,content_hash,merkle_root,actual_file_hash,mimetype,write_marker,thumbnail_hash, actual_thumbnail_hash) +VALUES (1234,'exampleId','exampleId:examplePath','exampleId:examplePath','f','filename','examplePath','someHash','customMeta','contentHash','merkleRoot','actualFileHash','mimetype','writeMarker','thumbnailHash','actualThumbnailHash'); +`) + if err != nil { + return err + } + + err = tx.Commit() + if err != nil { + return err + } + + return nil +} + +func (c *TestDataController) AddListEntitiesTestData(allocationTx, pubkey string) error { + var err error + var tx *sql.Tx + defer func() { + if err != nil { + if tx != nil { + errRollback := tx.Rollback() + if errRollback != nil { + log.Println(errRollback) + } + } + } + }() + + db, err := c.db.DB() + if err != nil { + return err + } + + tx, err = db.BeginTx(context.Background(), &sql.TxOptions{}) + if err != nil { + return err + } + + expTime := time.Now().Add(time.Hour * 100000).UnixNano() + + _, err = tx.Exec(` +INSERT INTO allocations (id, tx, owner_id, owner_public_key, expiration_date, payer_id) +VALUES ('exampleId' ,'` + allocationTx + `','exampleOwnerId','` + pubkey + `',` + fmt.Sprint(expTime) + `,'examplePayerId'); +`) + if err != nil { + return err + } + + _, err = tx.Exec(` +INSERT INTO reference_objects (id, allocation_id, path_hash,lookup_hash,type,name,path,hash,custom_meta,content_hash,merkle_root,actual_file_hash,mimetype,write_marker,thumbnail_hash, actual_thumbnail_hash) +VALUES (1234,'exampleId','exampleId:examplePath','exampleId:examplePath','f','filename','examplePath','someHash','customMeta','contentHash','merkleRoot','actualFileHash','mimetype','writeMarker','thumbnailHash','actualThumbnailHash'); +`) + if err != nil { + return err + } + + err = tx.Commit() + if err != nil { + return err + } + + return nil +} + +func (c *TestDataController) AddGetObjectPathTestData(allocationTx, pubKey string) error { + var err error + var tx *sql.Tx + defer func() { + if err != nil { + if tx != nil { + errRollback := tx.Rollback() + if errRollback != nil { + log.Println(errRollback) + } + } + } + }() + + db, err := c.db.DB() + if err != nil { + return err + } + + tx, err = db.BeginTx(context.Background(), &sql.TxOptions{}) + if err != nil { + return err + } + + expTime := time.Now().Add(time.Hour * 100000).UnixNano() + + _, err = tx.Exec(` +INSERT INTO allocations (id, tx, owner_id, owner_public_key, expiration_date, payer_id) +VALUES ('exampleId' ,'` + allocationTx + `','exampleOwnerId','` + pubKey + `',` + fmt.Sprint(expTime) + `,'examplePayerId'); +`) + if err != nil { + return err + } + + err = tx.Commit() + if err != nil { + return err + } + + return nil +} + +func (c *TestDataController) AddGetReferencePathTestData(allocationTx, pubkey string) error { + var err error + var tx *sql.Tx + defer func() { + if err != nil { + if tx != nil { + errRollback := tx.Rollback() + if errRollback != nil { + log.Println(errRollback) + } + } + } + }() + + db, err := c.db.DB() + if err != nil { + return err + } + + tx, err = db.BeginTx(context.Background(), &sql.TxOptions{}) + if err != nil { + return err + } + + expTime := time.Now().Add(time.Hour * 100000).UnixNano() + + _, err = tx.Exec(` +INSERT INTO allocations (id, tx, owner_id, owner_public_key, expiration_date, payer_id) +VALUES ('exampleId' ,'` + allocationTx + `','exampleOwnerId','` + pubkey + `',` + fmt.Sprint(expTime) + `,'examplePayerId'); +`) + if err != nil { + return err + } + + err = tx.Commit() + if err != nil { + return err + } + + return nil +} + +func (c *TestDataController) AddGetObjectTreeTestData(allocationTx, pubkey string) error { + var err error + var tx *sql.Tx + defer func() { + if err != nil { + if tx != nil { + errRollback := tx.Rollback() + if errRollback != nil { + log.Println(errRollback) + } + } + } + }() + + db, err := c.db.DB() + if err != nil { + return err + } + + tx, err = db.BeginTx(context.Background(), &sql.TxOptions{}) + if err != nil { + return err + } + + expTime := time.Now().Add(time.Hour * 100000).UnixNano() + + _, err = tx.Exec(` +INSERT INTO allocations (id, tx, owner_id, owner_public_key, expiration_date, payer_id) +VALUES ('exampleId' ,'` + allocationTx + `','exampleOwnerId','` + pubkey + `',` + fmt.Sprint(expTime) + `,'examplePayerId'); +`) + if err != nil { + return err + } + + _, err = tx.Exec(` +INSERT INTO reference_objects (id, allocation_id, path_hash,lookup_hash,type,name,path,hash,custom_meta,content_hash,merkle_root,actual_file_hash,mimetype,write_marker,thumbnail_hash, actual_thumbnail_hash) +VALUES (1234,'exampleId','exampleId:examplePath','exampleId:examplePath','d','root','/','someHash','customMeta','contentHash','merkleRoot','actualFileHash','mimetype','writeMarker','thumbnailHash','actualThumbnailHash'); +`) + if err != nil { + return err + } + + err = tx.Commit() + if err != nil { + return err + } + + return nil +} + func GeneratePubPrivateKey(t *testing.T) (string, string, zcncrypto.SignatureScheme) { - config.Configuration.Config = &coreConfig.Config{SignatureScheme: "bls0chain"} - signScheme := zcncrypto.NewSignatureScheme(config.Configuration.SignatureScheme) + signScheme := zcncrypto.NewSignatureScheme("bls0chain") wallet, err := signScheme.GenerateKeys() if err != nil { t.Fatal(err) @@ -77,3 +489,20 @@ func GeneratePubPrivateKey(t *testing.T) (string, string, zcncrypto.SignatureSch return keyPair.PublicKey, keyPair.PrivateKey, signScheme } + +func setupIntegrationTestConfig(t *testing.T) { + + pwd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + configDir := strings.Split(pwd, "/code/go")[0] + "/config" + config.SetupDefaultConfig() + config.SetupConfig(configDir) + + config.Configuration.DBHost = "localhost" + config.Configuration.DBName = viper.GetString("db.name") + config.Configuration.DBPort = viper.GetString("db.port") + config.Configuration.DBUserName = viper.GetString("db.user") + config.Configuration.DBPassword = viper.GetString("db.password") +} diff --git a/code/go/0chain.net/blobbercore/handler/grpc_handler_integration_test.go b/code/go/0chain.net/blobbercore/handler/grpc_handler_integration_test.go new file mode 100644 index 000000000..bde386249 --- /dev/null +++ b/code/go/0chain.net/blobbercore/handler/grpc_handler_integration_test.go @@ -0,0 +1,527 @@ +package handler + +import ( + "context" + "fmt" + "log" + "os" + "testing" + "time" + + "github.com/0chain/blobber/code/go/0chain.net/core/common" + + "google.golang.org/grpc/metadata" + + "github.com/0chain/blobber/code/go/0chain.net/core/encryption" + + "gorm.io/driver/postgres" + "gorm.io/gorm" + + "github.com/0chain/blobber/code/go/0chain.net/blobbercore/blobbergrpc" + "github.com/0chain/blobber/code/go/0chain.net/blobbercore/config" + "google.golang.org/grpc" +) + +const BlobberTestAddr = "localhost:7031" +const RetryAttempts = 8 +const RetryTimeout = 3 + +func TestBlobberGRPCService_IntegrationTest(t *testing.T) { + args := make(map[string]bool) + for _, arg := range os.Args { + args[arg] = true + } + if !args["integration"] { + t.Skip() + } + + var conn *grpc.ClientConn + var err error + for i := 0; i < RetryAttempts; i++ { + log.Println("Connection attempt - " + fmt.Sprint(i+1)) + conn, err = grpc.Dial(BlobberTestAddr, grpc.WithInsecure()) + if err != nil { + log.Println(err) + <-time.After(time.Second * RetryTimeout) + continue + } + break + } + if err != nil { + t.Fatal(err) + } + defer conn.Close() + blobberClient := blobbergrpc.NewBlobberClient(conn) + + setupIntegrationTestConfig(t) + db, err := gorm.Open(postgres.Open(fmt.Sprintf( + "host=%v port=%v user=%v dbname=%v password=%v sslmode=disable", + config.Configuration.DBHost, config.Configuration.DBPort, + config.Configuration.DBUserName, config.Configuration.DBName, + config.Configuration.DBPassword)), &gorm.Config{}) + if err != nil { + t.Fatal(err) + } + tdController := NewTestDataController(db) + + t.Run("TestGetAllocation", func(t *testing.T) { + err := tdController.ClearDatabase() + if err != nil { + t.Fatal(err) + } + err = tdController.AddGetAllocationTestData() + if err != nil { + t.Fatal(err) + } + + testCases := []struct { + name string + input *blobbergrpc.GetAllocationRequest + expectedTx string + expectingError bool + }{ + { + name: "Success", + input: &blobbergrpc.GetAllocationRequest{ + Id: "exampleTransaction", + }, + expectedTx: "exampleTransaction", + expectingError: false, + }, + { + name: "UnknownAllocation", + input: &blobbergrpc.GetAllocationRequest{ + Id: "exampleTransaction1", + }, + expectedTx: "", + expectingError: true, + }, + } + + for _, tc := range testCases { + getAllocationResp, err := blobberClient.GetAllocation(context.Background(), tc.input) + if err != nil { + if !tc.expectingError { + t.Fatal(err) + } + continue + } + + if tc.expectingError { + t.Fatal("expected error") + } + + if getAllocationResp.Allocation.Tx != tc.expectedTx { + t.Fatal("response with wrong allocation transaction") + } + } + }) + + t.Run("TestGetFileMetaData", func(t *testing.T) { + err := tdController.ClearDatabase() + if err != nil { + t.Fatal(err) + } + err = tdController.AddGetFileMetaDataTestData() + if err != nil { + t.Fatal(err) + } + + testCases := []struct { + name string + context metadata.MD + input *blobbergrpc.GetFileMetaDataRequest + expectedFileName string + expectingError bool + }{ + { + name: "Success", + context: metadata.New(map[string]string{ + common.ClientHeader: "exampleOwnerId", + }), + input: &blobbergrpc.GetFileMetaDataRequest{ + Path: "examplePath", + PathHash: "exampleId:examplePath", + Allocation: "exampleTransaction", + }, + expectedFileName: "filename", + expectingError: false, + }, + { + name: "Unknown file path", + context: metadata.New(map[string]string{ + common.ClientHeader: "exampleOwnerId", + }), + input: &blobbergrpc.GetFileMetaDataRequest{ + Path: "examplePath", + PathHash: "exampleId:examplePath123", + Allocation: "exampleTransaction", + }, + expectedFileName: "", + expectingError: true, + }, + } + + for _, tc := range testCases { + ctx := context.Background() + ctx = metadata.NewOutgoingContext(ctx, tc.context) + getFileMetaDataResp, err := blobberClient.GetFileMetaData(ctx, tc.input) + if err != nil { + if !tc.expectingError { + t.Fatal(err) + } + continue + } + + if tc.expectingError { + t.Fatal("expected error") + } + + if getFileMetaDataResp.MetaData.FileMetaData.Name != tc.expectedFileName { + t.Fatal("unexpected file name from GetFileMetaData rpc") + } + } + }) + + t.Run("TestGetFileStats", func(t *testing.T) { + + allocationTx := randString(32) + + pubKey, _, signScheme := GeneratePubPrivateKey(t) + clientSignature, _ := signScheme.Sign(encryption.Hash(allocationTx)) + + err := tdController.ClearDatabase() + if err != nil { + t.Fatal(err) + } + err = tdController.AddGetFileStatsTestData(allocationTx, pubKey) + if err != nil { + t.Fatal(err) + } + + testCases := []struct { + name string + context metadata.MD + input *blobbergrpc.GetFileStatsRequest + expectedFileName string + expectingError bool + }{ + { + name: "Success", + context: metadata.New(map[string]string{ + common.ClientHeader: "exampleOwnerId", + common.ClientSignatureHeader: clientSignature, + }), + input: &blobbergrpc.GetFileStatsRequest{ + Path: "examplePath", + PathHash: "exampleId:examplePath", + Allocation: allocationTx, + }, + expectedFileName: "filename", + expectingError: false, + }, + { + name: "Unknown Path", + context: metadata.New(map[string]string{ + common.ClientHeader: "exampleOwnerId", + common.ClientSignatureHeader: clientSignature, + }), + input: &blobbergrpc.GetFileStatsRequest{ + Path: "examplePath", + PathHash: "exampleId:examplePath123", + Allocation: allocationTx, + }, + expectedFileName: "", + expectingError: true, + }, + } + + for _, tc := range testCases { + ctx := context.Background() + ctx = metadata.NewOutgoingContext(ctx, tc.context) + getFileStatsResp, err := blobberClient.GetFileStats(ctx, tc.input) + if err != nil { + if !tc.expectingError { + t.Fatal(err) + } + continue + } + + if tc.expectingError { + t.Fatal("expected error") + } + + if getFileStatsResp.MetaData.FileMetaData.Name != tc.expectedFileName { + t.Fatal("unexpected file name from GetFileStats rpc") + } + } + + }) + + t.Run("TestListEntities", func(t *testing.T) { + allocationTx := randString(32) + + pubKey, _, signScheme := GeneratePubPrivateKey(t) + clientSignature, _ := signScheme.Sign(encryption.Hash(allocationTx)) + + err := tdController.ClearDatabase() + if err != nil { + t.Fatal(err) + } + err = tdController.AddListEntitiesTestData(allocationTx, pubKey) + if err != nil { + t.Fatal(err) + } + + testCases := []struct { + name string + context metadata.MD + input *blobbergrpc.ListEntitiesRequest + expectedPath string + expectingError bool + }{ + { + name: "Success", + context: metadata.New(map[string]string{ + common.ClientHeader: "exampleOwnerId", + common.ClientSignatureHeader: clientSignature, + }), + input: &blobbergrpc.ListEntitiesRequest{ + Path: "examplePath", + PathHash: "exampleId:examplePath", + AuthToken: "", + Allocation: allocationTx, + }, + expectedPath: "examplePath", + expectingError: false, + }, + { + name: "bad path", + context: metadata.New(map[string]string{ + common.ClientHeader: "exampleOwnerId", + common.ClientSignatureHeader: clientSignature, + }), + input: &blobbergrpc.ListEntitiesRequest{ + Path: "examplePath", + PathHash: "exampleId:examplePath123", + AuthToken: "", + Allocation: allocationTx, + }, + expectedPath: "", + expectingError: true, + }, + } + + for _, tc := range testCases { + ctx := context.Background() + ctx = metadata.NewOutgoingContext(ctx, tc.context) + listEntitiesResp, err := blobberClient.ListEntities(ctx, tc.input) + if err != nil { + if !tc.expectingError { + t.Fatal(err) + } + continue + } + + if tc.expectingError { + t.Fatal("expected error") + } + + if listEntitiesResp.MetaData.DirMetaData.Path != tc.expectedPath { + t.Fatal("unexpected path from ListEntities rpc") + } + } + + }) + + t.Run("TestGetObjectPath", func(t *testing.T) { + allocationTx := randString(32) + + pubKey, _, signScheme := GeneratePubPrivateKey(t) + clientSignature, _ := signScheme.Sign(encryption.Hash(allocationTx)) + + err := tdController.ClearDatabase() + if err != nil { + t.Fatal(err) + } + err = tdController.AddGetObjectPathTestData(allocationTx, pubKey) + if err != nil { + t.Fatal(err) + } + + testCases := []struct { + name string + context metadata.MD + input *blobbergrpc.GetObjectPathRequest + expectedPath string + expectingError bool + }{ + { + name: "Success", + context: metadata.New(map[string]string{ + common.ClientHeader: "exampleOwnerId", + common.ClientSignatureHeader: clientSignature, + }), + input: &blobbergrpc.GetObjectPathRequest{ + Allocation: allocationTx, + Path: "examplePath", + BlockNum: "0", + }, + expectedPath: "/", + expectingError: false, + }, + } + + for _, tc := range testCases { + ctx := context.Background() + ctx = metadata.NewOutgoingContext(ctx, tc.context) + getObjectPathResp, err := blobberClient.GetObjectPath(ctx, tc.input) + if err != nil { + if !tc.expectingError { + t.Fatal(err) + } + continue + } + + if tc.expectingError { + t.Fatal("expected error") + } + + if getObjectPathResp.ObjectPath.Path.DirMetaData.Path != tc.expectedPath { + t.Fatal("unexpected root hash from GetObjectPath rpc") + } + } + }) + + t.Run("TestGetReferencePath", func(t *testing.T) { + allocationTx := randString(32) + + pubKey, _, signScheme := GeneratePubPrivateKey(t) + clientSignature, _ := signScheme.Sign(encryption.Hash(allocationTx)) + + err := tdController.ClearDatabase() + if err != nil { + t.Fatal(err) + } + err = tdController.AddGetReferencePathTestData(allocationTx, pubKey) + if err != nil { + t.Fatal(err) + } + + testCases := []struct { + name string + context metadata.MD + input *blobbergrpc.GetReferencePathRequest + expectedPath string + expectingError bool + }{ + { + name: "Success", + context: metadata.New(map[string]string{ + common.ClientHeader: "exampleOwnerId", + common.ClientSignatureHeader: clientSignature, + }), + input: &blobbergrpc.GetReferencePathRequest{ + Paths: "", + Path: "/", + Allocation: allocationTx, + }, + expectedPath: "/", + expectingError: false, + }, + } + + for _, tc := range testCases { + ctx := context.Background() + ctx = metadata.NewOutgoingContext(ctx, tc.context) + getReferencePathResp, err := blobberClient.GetReferencePath(ctx, tc.input) + if err != nil { + if !tc.expectingError { + t.Fatal(err) + } + continue + } + + if tc.expectingError { + t.Fatal("expected error") + } + + if getReferencePathResp.ReferencePath.MetaData.DirMetaData.Path != tc.expectedPath { + t.Fatal("unexpected path from GetReferencePath rpc") + } + } + }) + + t.Run("TestGetObjectTree", func(t *testing.T) { + allocationTx := randString(32) + + pubKey, _, signScheme := GeneratePubPrivateKey(t) + clientSignature, _ := signScheme.Sign(encryption.Hash(allocationTx)) + + err := tdController.ClearDatabase() + if err != nil { + t.Fatal(err) + } + err = tdController.AddGetObjectTreeTestData(allocationTx, pubKey) + if err != nil { + t.Fatal(err) + } + + testCases := []struct { + name string + context metadata.MD + input *blobbergrpc.GetObjectTreeRequest + expectedFileName string + expectingError bool + }{ + { + name: "Success", + context: metadata.New(map[string]string{ + common.ClientHeader: "exampleOwnerId", + common.ClientSignatureHeader: clientSignature, + }), + input: &blobbergrpc.GetObjectTreeRequest{ + Path: "/", + Allocation: allocationTx, + }, + expectedFileName: "root", + expectingError: false, + }, + { + name: "bad path", + context: metadata.New(map[string]string{ + common.ClientHeader: "exampleOwnerId", + common.ClientSignatureHeader: clientSignature, + }), + input: &blobbergrpc.GetObjectTreeRequest{ + Path: "/2", + Allocation: "", + }, + expectedFileName: "root", + expectingError: true, + }, + } + + for _, tc := range testCases { + ctx := context.Background() + ctx = metadata.NewOutgoingContext(ctx, tc.context) + getObjectTreeResp, err := blobberClient.GetObjectTree(ctx, tc.input) + if err != nil { + if !tc.expectingError { + t.Fatal(err) + } + continue + } + + if tc.expectingError { + t.Fatal("expected error") + } + + if getObjectTreeResp.ReferencePath.MetaData.DirMetaData.Name != tc.expectedFileName { + t.Fatal("unexpected root name from GetObject") + } + } + + }) + +} diff --git a/code/go/0chain.net/core/common/rate_limiter.go b/code/go/0chain.net/core/common/rate_limiter.go index a4cacdda0..6bb04168f 100644 --- a/code/go/0chain.net/core/common/rate_limiter.go +++ b/code/go/0chain.net/core/common/rate_limiter.go @@ -32,7 +32,7 @@ func (rl *ratelimit) init() { const DefaultRequestPerSecond = 100000 //ConfigRateLimits - configure the rate limits -func ConfigRateLimits() *GRPCRateLimiter { +func ConfigRateLimits() { userRl := viper.GetFloat64("handlers.rate_limit") if userRl == 0 { @@ -41,6 +41,14 @@ func ConfigRateLimits() *GRPCRateLimiter { userRateLimit = &ratelimit{RequestsPerSecond: userRl} userRateLimit.init() +} + +func NewGRPCRateLimiter() *GRPCRateLimiter { + userRl := viper.GetFloat64("handlers.rate_limit") + + if userRl == 0 { + userRl = DefaultRequestPerSecond + } return &GRPCRateLimiter{rl.New(int(userRl))} } diff --git a/docker.local/b0docker-compose.yml b/docker.local/b0docker-compose.yml index 6030b1930..64672a94c 100644 --- a/docker.local/b0docker-compose.yml +++ b/docker.local/b0docker-compose.yml @@ -7,6 +7,8 @@ services: POSTGRES_HOST: postgres POSTGRES_USER: postgres POSTGRES_HOST_AUTH_METHOD: trust + ports: + - "5432:5432" volumes: - ./blobber${BLOBBER}/data/postgresql:/var/lib/postgresql/data networks: