From 8e3d63c1940df26fd00bb2850924e1311f36ad10 Mon Sep 17 00:00:00 2001 From: anandrgitnirman Date: Thu, 28 Nov 2019 10:39:06 +0530 Subject: [PATCH] https://github.com/singnet/snet-daemon/issues/426 service metadata now has a place holder to define the number of free calls allowed .Give placeholders to use this field More test cases for coverage and go fmt formatting --- blockchain/serviceMetadata.go | 89 ++++++++++++++++-------------- blockchain/serviceMetadata_test.go | 44 +++++++++++---- 2 files changed, 79 insertions(+), 54 deletions(-) diff --git a/blockchain/serviceMetadata.go b/blockchain/serviceMetadata.go index 0a7ddfd3..c0b780a0 100644 --- a/blockchain/serviceMetadata.go +++ b/blockchain/serviceMetadata.go @@ -12,6 +12,7 @@ import ( "math/big" "strings" ) + /* { "version": 1, @@ -57,50 +58,49 @@ import ( const IpfsPrefix = "ipfs://" type ServiceMetadata struct { - Version int `json:"version"` - DisplayName string `json:"display_name"` - Encoding string `json:"encoding"` - ServiceType string `json:"service_type"` - Groups []OrganizationGroup `json:"groups"` - ModelIpfsHash string `json:"model_ipfs_hash"` - MpeAddress string `json:"mpe_address"` - - multiPartyEscrowAddress common.Address - defaultPricing Pricing - - defaultGroup OrganizationGroup - - freeCallSignerAddress common.Address - isfreeCallAllowed bool + Version int `json:"version"` + DisplayName string `json:"display_name"` + Encoding string `json:"encoding"` + ServiceType string `json:"service_type"` + Groups []OrganizationGroup `json:"groups"` + ModelIpfsHash string `json:"model_ipfs_hash"` + MpeAddress string `json:"mpe_address"` + + multiPartyEscrowAddress common.Address + defaultPricing Pricing + + defaultGroup OrganizationGroup + + freeCallSignerAddress common.Address + isfreeCallAllowed bool + freeCallsAllowed int } type OrganizationGroup struct { - Endpoints []string `json:"endpoints"` - GroupID string `json:"group_id"` - GroupName string `json:"group_name"` - Pricing []Pricing `json:"pricing"` - FreeCalls int `json:"free_calls"` - FreeCallSigner string `json:"free_call_signer_address"` + Endpoints []string `json:"endpoints"` + GroupID string `json:"group_id"` + GroupName string `json:"group_name"` + Pricing []Pricing `json:"pricing"` + FreeCalls int `json:"free_calls"` + FreeCallSigner string `json:"free_call_signer_address"` } type Pricing struct { - PriceModel string `json:"price_model"` - PriceInCogs *big.Int `json:"price_in_cogs,omitempty"` - PackageName string `json:"package_name,omitempty"` - Default bool `json:"default,omitempty"` + PriceModel string `json:"price_model"` + PriceInCogs *big.Int `json:"price_in_cogs,omitempty"` + PackageName string `json:"package_name,omitempty"` + Default bool `json:"default,omitempty"` PricingDetails []PricingDetails `json:"details,omitempty"` } type PricingDetails struct { - ServiceName string `json:"service_name"` + ServiceName string `json:"service_name"` MethodPricing []MethodPricing `json:"method_pricing"` } type MethodPricing struct { - MethodName string `json:"method_name"` - PriceInCogs *big.Int `json:"price_in_cogs"` + MethodName string `json:"method_name"` + PriceInCogs *big.Int `json:"price_in_cogs"` } - - func getRegistryAddressKey() common.Address { address := config.GetRegistryAddress() return common.HexToAddress(address) @@ -121,7 +121,7 @@ func ServiceMetaData() *ServiceMetadata { Panic("error on determining service metadata from file") } } else { - metadata = &ServiceMetadata{Encoding:"proto",ServiceType:"grpc"} + metadata = &ServiceMetadata{Encoding: "proto", ServiceType: "grpc"} } return metadata } @@ -188,16 +188,16 @@ func InitServiceMetaDataFromJson(jsonData string) (*ServiceMetadata, error) { } if err := setDerivedFields(metaData); err != nil { - return nil,err + return nil, err } - if err := setFreeCallData(metaData) ; err != nil { - return nil,err + if err := setFreeCallData(metaData); err != nil { + return nil, err } return metaData, err } func setDerivedFields(metaData *ServiceMetadata) (err error) { - if err= setDefaultPricing(metaData); err != nil { + if err = setDefaultPricing(metaData); err != nil { return err } setMultiPartyEscrowAddress(metaData) @@ -211,23 +211,23 @@ func setGroup(metaData *ServiceMetadata) (err error) { for _, group := range metaData.Groups { if strings.Compare(group.GroupName, groupName) == 0 { metaData.defaultGroup = group - return nil + return nil } } err = fmt.Errorf("group name %v in config is invalid, "+ "there was no group found with this name in the metadata", groupName) log.WithError(err) - return err + return err } func setDefaultPricing(metaData *ServiceMetadata) (err error) { - if err = setGroup(metaData);err != nil { + if err = setGroup(metaData); err != nil { return err } for _, pricing := range metaData.defaultGroup.Pricing { if pricing.Default { metaData.defaultPricing = pricing - return nil + return nil } } err = fmt.Errorf("MetaData does not have the default pricing set ") @@ -240,10 +240,11 @@ func setMultiPartyEscrowAddress(metaData *ServiceMetadata) { metaData.multiPartyEscrowAddress = common.HexToAddress(metaData.MpeAddress) } -func setFreeCallData(metaData *ServiceMetadata) (error) { +func setFreeCallData(metaData *ServiceMetadata) error { - if (metaData.defaultGroup.FreeCalls > 0 ) { + if metaData.defaultGroup.FreeCalls > 0 { metaData.isfreeCallAllowed = true + metaData.freeCallsAllowed = metaData.defaultGroup.FreeCalls //If the signer address is not a valid address, then return back an error if !common.IsHexAddress((metaData.defaultGroup.FreeCallSigner)) { return fmt.Errorf("MetaData does not have 'free_call_signer_address defined correctly") @@ -282,4 +283,8 @@ func (metaData *ServiceMetadata) GetDisplayName() string { func (metaData *ServiceMetadata) IsFreeCallAllowed() bool { return metaData.isfreeCallAllowed -} \ No newline at end of file +} + +func (metaData *ServiceMetadata) GetFreeCallsAllowed() int { + return metaData.freeCallsAllowed +} diff --git a/blockchain/serviceMetadata_test.go b/blockchain/serviceMetadata_test.go index 8998ae64..780b983c 100644 --- a/blockchain/serviceMetadata_test.go +++ b/blockchain/serviceMetadata_test.go @@ -1,19 +1,20 @@ package blockchain import ( - "github.com/ethereum/go-ethereum/common" - "github.com/singnet/snet-daemon/config" - "github.com/stretchr/testify/assert" "math/big" "strings" "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/singnet/snet-daemon/config" + "github.com/stretchr/testify/assert" ) var testJsonData = "{ \"version\": 1, \"display_name\": \"Example1\", \"encoding\": \"grpc\", \"service_type\": \"grpc\", \"payment_expiration_threshold\": 40320, \"model_ipfs_hash\": \"Qmdiq8Hu6dYiwp712GtnbBxagyfYyvUY1HYqkH7iN76UCc\", " + " \"mpe_address\": \"0x7E6366Fbe3bdfCE3C906667911FC5237Cc96BD08\", \"groups\": [ { \"free_calls\": 12, \"free_call_signer_address\": \"0x7DF35C98f41F3Af0df1dc4c7F7D4C19a71Dd059F\", \"endpoints\": [\"http://34.344.33.1:2379\",\"http://34.344.33.1:2389\"], \"group_id\": \"88ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\",\"group_name\": \"default_group\", \"pricing\": [ { \"price_model\": \"fixed_price\", \"price_in_cogs\": 2 }, { \"package_name\": \"example_service\", \"price_model\": \"fixed_price_per_method\", \"default\":true, \"details\": [ { \"service_name\": \"Calculator\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 2 }, { \"method_name\": \"mul\", \"price_in_cogs\": 3 } ] }, { \"service_name\": \"Calculator2\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 3 }, { \"method_name\": \"mul\", \"price_in_cogs\": 2 } ] } ] }] }, { \"endpoints\": [\"http://97.344.33.1:2379\",\"http://67.344.33.1:2389\"], \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"pricing\": [ { \"package_name\": \"example_service\", \"price_model\": \"fixed_price_per_method\", \"details\": [ { \"service_name\": \"Calculator\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 2 }, { \"method_name\": \"mul\", \"price_in_cogs\": 3 } ] }, { \"service_name\": \"Calculator2\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 3 }, { \"method_name\": \"mul\", \"price_in_cogs\": 2 } ] } ] }] } ] } " func TestAllGetterMethods(t *testing.T) { - config.Vip().Set(config.FreeCallEndPoint,"http://demo8325345.mockable.io") + config.Vip().Set(config.FreeCallEndPoint, "http://demo8325345.mockable.io") metaData, err := InitServiceMetaDataFromJson(testJsonData) assert.Equal(t, err, nil) @@ -21,20 +22,18 @@ func TestAllGetterMethods(t *testing.T) { assert.Equal(t, metaData.GetDisplayName(), "Example1") assert.Equal(t, metaData.GetServiceType(), "grpc") assert.Equal(t, metaData.GetWireEncoding(), "grpc") - assert.Nil(t,metaData.GetDefaultPricing().PriceInCogs) + assert.Nil(t, metaData.GetDefaultPricing().PriceInCogs) assert.Equal(t, metaData.GetDefaultPricing().PricingDetails[0].MethodPricing[0].PriceInCogs, big.NewInt(2)) assert.Equal(t, metaData.GetMpeAddress(), common.HexToAddress("0x7E6366Fbe3bdfCE3C906667911FC5237Cc96BD08")) assert.Equal(t, metaData.FreeCallSignerAddress(), common.HexToAddress("0x7DF35C98f41F3Af0df1dc4c7F7D4C19a71Dd059F")) assert.True(t, metaData.IsFreeCallAllowed()) - - + assert.Equal(t, 12, metaData.GetFreeCallsAllowed()) } - func TestInitServiceMetaDataFromJson(t *testing.T) { //Parse Bad JSON - _, err := InitServiceMetaDataFromJson(strings.Replace(testJsonData, "{", "", 1)) + _, err := InitServiceMetaDataFromJson(strings.Replace(testJsonData, "{", "", 1)) if err != nil { assert.Equal(t, err.Error(), "invalid character ':' after top-level value") } @@ -44,7 +43,11 @@ func TestInitServiceMetaDataFromJson(t *testing.T) { if err != nil { assert.Equal(t, err.Error(), "MetaData does not have 'free_call_signer_address defined correctly") } - config.Vip().Set(config.FreeCallEndPoint,"badurl") + _, err = InitServiceMetaDataFromJson(strings.Replace(testJsonData, "default_pricing", "dummy", 1)) + if err != nil { + assert.Equal(t, err.Error(), "MetaData does not have the default pricing set ") + } + config.Vip().Set(config.FreeCallEndPoint, "badurl") _, err = InitServiceMetaDataFromJson(testJsonData) if err != nil { assert.Equal(t, err.Error(), "Please specify a valid end point for 'free_call_end_point' tracking usage of free calls ") @@ -52,10 +55,27 @@ func TestInitServiceMetaDataFromJson(t *testing.T) { } func TestReadServiceMetaDataFromLocalFile(t *testing.T) { - - metadata, err := ReadServiceMetaDataFromLocalFile("../service_metadata.json") assert.Equal(t, err, nil) assert.Equal(t, metadata.Version, 1) +} + +func Test_getServiceMetaDataUrifromRegistry(t *testing.T) { + assert.Panics(t, func() { getServiceMetaDataUrifromRegistry() }) + config.Vip().Set(config.BlockChainNetworkSelected, "ropsten") + config.Validate() + assert.Panics(t, func() { getServiceMetaDataUrifromRegistry() }) + +} + +func Test_setDefaultPricing(t *testing.T) { + err := setDefaultPricing(&ServiceMetadata{}) + assert.NotNil(t, err) + err = setDefaultPricing(&ServiceMetadata{Groups: []OrganizationGroup{{GroupName: "default_group"}}}) + assert.Equal(t, err.Error(), "MetaData does not have the default pricing set ") +} +func Test_setGroup(t *testing.T) { + err := setGroup(&ServiceMetadata{}) + assert.Equal(t, err.Error(), "group name default_group in config is invalid, there was no group found with this name in the metadata") }