mirror of
https://github.com/absmach/magistrala.git
synced 2026-06-23 04:10:28 +00:00
MF-1718 - Use static code analysis in CI (#1729)
* things, twins, and logger lint fixed Signed-off-by: aryan <aryangodara03@gmail.com> * all services updated, auth jwt not working, ineffectual assignment issue Signed-off-by: aryan <aryangodara03@gmail.com> * handle error from grpc server in endpointtest Signed-off-by: aryan <aryangodara03@gmail.com> * temp commit, auth/jwt needs to be resolved Signed-off-by: aryan <aryangodara03@gmail.com> * revert back to jwt v4 temporarily Signed-off-by: aryan <aryangodara03@gmail.com> * updated jwt tokenizer Signed-off-by: aryan <aryangodara03@gmail.com> * resolve EOF error for httptest requests Signed-off-by: aryan <aryangodara03@gmail.com> * fix auth jwt, update to registeredclaims Signed-off-by: aryan <aryangodara03@gmail.com> * fix ineffective assignment, auth/api/grpc endpoint failing Signed-off-by: aryan <aryangodara03@gmail.com> * temp commit, remove later Signed-off-by: aryan <aryangodara03@gmail.com> * fix grpc server setup Signed-off-by: aryan <aryangodara03@gmail.com> * resolve golangci tests, remove debug statements Signed-off-by: aryan <aryangodara03@gmail.com> * update golangci version and modify linters used Signed-off-by: aryan <aryangodara03@gmail.com> * fix failing tests Signed-off-by: aryan <aryangodara03@gmail.com> * fix grpc server for setup tests Signed-off-by: aryan <aryangodara03@gmail.com> * fix logging and errors inlined Signed-off-by: aryan <aryangodara03@gmail.com> * fix remarks, update grpc setup_test Signed-off-by: aryan <aryangodara03@gmail.com> * fix setup_test Signed-off-by: aryan <aryangodara03@gmail.com> * update setup_test grpc Signed-off-by: aryan <aryangodara03@gmail.com> * fix data race Signed-off-by: aryan <aryangodara03@gmail.com> * update setup_test grpc Signed-off-by: aryan <aryangodara03@gmail.com> * fix grpc setup down to single simple function Signed-off-by: aryan <aryangodara03@gmail.com> * fix linting issues Signed-off-by: aryan <aryangodara03@gmail.com> * resolve pr comments Signed-off-by: aryan <aryangodara03@gmail.com> * fix tests, handle returned errors, go mod tidy vendor Signed-off-by: aryan <aryangodara03@gmail.com> * fix errors from new linters Signed-off-by: aryan <aryangodara03@gmail.com> --------- Signed-off-by: aryan <aryangodara03@gmail.com>
This commit is contained in:
@@ -6,15 +6,12 @@ package grpc_test
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/mainflux/mainflux"
|
||||
"github.com/mainflux/mainflux/auth"
|
||||
grpcapi "github.com/mainflux/mainflux/auth/api/grpc"
|
||||
"github.com/mainflux/mainflux/auth/jwt"
|
||||
"github.com/mainflux/mainflux/auth/mocks"
|
||||
"github.com/mainflux/mainflux/pkg/uuid"
|
||||
"github.com/opentracing/opentracing-go/mocktracer"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -44,30 +41,11 @@ const (
|
||||
|
||||
var svc auth.Service
|
||||
|
||||
func newService() auth.Service {
|
||||
repo := mocks.NewKeyRepository()
|
||||
groupRepo := mocks.NewGroupRepository()
|
||||
idProvider := uuid.NewMock()
|
||||
|
||||
mockAuthzDB := map[string][]mocks.MockSubjectSet{}
|
||||
mockAuthzDB[id] = append(mockAuthzDB[id], mocks.MockSubjectSet{Object: authoritiesObj, Relation: memberRelation})
|
||||
ketoMock := mocks.NewKetoMock(mockAuthzDB)
|
||||
|
||||
t := jwt.New(secret)
|
||||
|
||||
return auth.New(repo, groupRepo, idProvider, t, ketoMock, loginDuration)
|
||||
}
|
||||
|
||||
func startGRPCServer(svc auth.Service, port int) {
|
||||
listener, _ := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||
server := grpc.NewServer()
|
||||
mainflux.RegisterAuthServiceServer(server, grpcapi.NewServer(mocktracer.New(), svc))
|
||||
go server.Serve(listener)
|
||||
}
|
||||
|
||||
func TestIssue(t *testing.T) {
|
||||
authAddr := fmt.Sprintf("localhost:%d", port)
|
||||
conn, _ := grpc.Dial(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
conn, err := grpc.Dial(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
require.Nil(t, err, fmt.Sprintf("got unexpected error while creating client connection: %s", err))
|
||||
|
||||
client := grpcapi.NewClient(mocktracer.New(), conn, time.Second)
|
||||
|
||||
cases := []struct {
|
||||
@@ -139,7 +117,9 @@ func TestIdentify(t *testing.T) {
|
||||
require.Nil(t, err, fmt.Sprintf("Issuing API key expected to succeed: %s", err))
|
||||
|
||||
authAddr := fmt.Sprintf("localhost:%d", port)
|
||||
conn, _ := grpc.Dial(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
conn, err := grpc.Dial(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
require.Nil(t, err, fmt.Sprintf("got unexpected error while creating client connection: %s", err))
|
||||
|
||||
client := grpcapi.NewClient(mocktracer.New(), conn, time.Second)
|
||||
|
||||
cases := []struct {
|
||||
@@ -202,7 +182,9 @@ func TestAuthorize(t *testing.T) {
|
||||
require.Nil(t, err, fmt.Sprintf("Issuing user key expected to succeed: %s", err))
|
||||
|
||||
authAddr := fmt.Sprintf("localhost:%d", port)
|
||||
conn, _ := grpc.Dial(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
conn, err := grpc.Dial(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
require.Nil(t, err, fmt.Sprintf("got unexpected error while creating client connection: %s", err))
|
||||
|
||||
client := grpcapi.NewClient(mocktracer.New(), conn, time.Second)
|
||||
|
||||
cases := []struct {
|
||||
@@ -283,7 +265,9 @@ func TestAddPolicy(t *testing.T) {
|
||||
require.Nil(t, err, fmt.Sprintf("Issuing user key expected to succeed: %s", err))
|
||||
|
||||
authAddr := fmt.Sprintf("localhost:%d", port)
|
||||
conn, _ := grpc.Dial(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
conn, err := grpc.Dial(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
require.Nil(t, err, fmt.Sprintf("got unexpected error while creating client connection: %s", err))
|
||||
|
||||
client := grpcapi.NewClient(mocktracer.New(), conn, time.Second)
|
||||
|
||||
groupAdminObj := "groupadmin"
|
||||
@@ -336,7 +320,9 @@ func TestDeletePolicy(t *testing.T) {
|
||||
require.Nil(t, err, fmt.Sprintf("Issuing user key expected to succeed: %s", err))
|
||||
|
||||
authAddr := fmt.Sprintf("localhost:%d", port)
|
||||
conn, _ := grpc.Dial(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
conn, err := grpc.Dial(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
require.Nil(t, err, fmt.Sprintf("got unexpected error while creating client connection: %s", err))
|
||||
|
||||
client := grpcapi.NewClient(mocktracer.New(), conn, time.Second)
|
||||
|
||||
readRelation := "read"
|
||||
@@ -452,7 +438,9 @@ func TestMembers(t *testing.T) {
|
||||
}
|
||||
|
||||
authAddr := fmt.Sprintf("localhost:%d", port)
|
||||
conn, _ := grpc.Dial(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
conn, err := grpc.Dial(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
require.Nil(t, err, fmt.Sprintf("got unexpected error while creating client connection: %s", err))
|
||||
|
||||
client := grpcapi.NewClient(mocktracer.New(), conn, time.Second)
|
||||
|
||||
for _, tc := range cases {
|
||||
|
||||
@@ -4,15 +4,60 @@
|
||||
package grpc_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/mainflux/mainflux"
|
||||
"github.com/mainflux/mainflux/auth"
|
||||
grpcapi "github.com/mainflux/mainflux/auth/api/grpc"
|
||||
"github.com/mainflux/mainflux/auth/jwt"
|
||||
"github.com/mainflux/mainflux/auth/mocks"
|
||||
"github.com/mainflux/mainflux/pkg/uuid"
|
||||
"github.com/opentracing/opentracing-go/mocktracer"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
serverErr := make(chan error)
|
||||
|
||||
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||
if err != nil {
|
||||
log.Fatalf("got unexpected error while creating new listerner: %s", err)
|
||||
}
|
||||
|
||||
svc = newService()
|
||||
startGRPCServer(svc, port)
|
||||
server := grpc.NewServer()
|
||||
mainflux.RegisterAuthServiceServer(server, grpcapi.NewServer(mocktracer.New(), svc))
|
||||
|
||||
// Start gRPC server in detached mode.
|
||||
go func() {
|
||||
serverErr <- server.Serve(listener)
|
||||
}()
|
||||
|
||||
code := m.Run()
|
||||
|
||||
server.GracefulStop()
|
||||
err = <-serverErr
|
||||
if err != nil {
|
||||
log.Fatalln("gPRC Server Terminated : ", err)
|
||||
}
|
||||
close(serverErr)
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
func newService() auth.Service {
|
||||
repo := mocks.NewKeyRepository()
|
||||
groupRepo := mocks.NewGroupRepository()
|
||||
idProvider := uuid.NewMock()
|
||||
|
||||
mockAuthzDB := map[string][]mocks.MockSubjectSet{}
|
||||
mockAuthzDB[id] = append(mockAuthzDB[id], mocks.MockSubjectSet{Object: authoritiesObj, Relation: memberRelation})
|
||||
ketoMock := mocks.NewKetoMock(mockAuthzDB)
|
||||
|
||||
tokenizer := jwt.New(secret)
|
||||
|
||||
return auth.New(repo, groupRepo, idProvider, tokenizer, ketoMock, loginDuration)
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ type testRequest struct {
|
||||
|
||||
func (tr testRequest) make() (*http.Response, error) {
|
||||
req, err := http.NewRequest(tr.method, tr.url, tr.body)
|
||||
req.Close = true
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+14
-11
@@ -14,7 +14,7 @@ import (
|
||||
const issuerName = "mainflux.auth"
|
||||
|
||||
type claims struct {
|
||||
jwt.StandardClaims
|
||||
jwt.RegisteredClaims
|
||||
IssuerID string `json:"issuer_id,omitempty"`
|
||||
Type *uint32 `json:"type,omitempty"`
|
||||
}
|
||||
@@ -24,7 +24,7 @@ func (c claims) Valid() error {
|
||||
return errors.ErrMalformedEntity
|
||||
}
|
||||
|
||||
return c.StandardClaims.Valid()
|
||||
return c.RegisteredClaims.Valid()
|
||||
}
|
||||
|
||||
type tokenizer struct {
|
||||
@@ -38,20 +38,20 @@ func New(secret string) auth.Tokenizer {
|
||||
|
||||
func (svc tokenizer) Issue(key auth.Key) (string, error) {
|
||||
claims := claims{
|
||||
StandardClaims: jwt.StandardClaims{
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
Issuer: issuerName,
|
||||
Subject: key.Subject,
|
||||
IssuedAt: key.IssuedAt.UTC().Unix(),
|
||||
IssuedAt: &jwt.NumericDate{Time: key.IssuedAt.UTC()},
|
||||
},
|
||||
IssuerID: key.IssuerID,
|
||||
Type: &key.Type,
|
||||
}
|
||||
|
||||
if !key.ExpiresAt.IsZero() {
|
||||
claims.ExpiresAt = key.ExpiresAt.UTC().Unix()
|
||||
claims.ExpiresAt = &jwt.NumericDate{Time: key.ExpiresAt.UTC()}
|
||||
}
|
||||
if key.ID != "" {
|
||||
claims.Id = key.ID
|
||||
claims.ID = key.ID
|
||||
}
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
@@ -70,6 +70,7 @@ func (svc tokenizer) Parse(token string) (auth.Key, error) {
|
||||
if err != nil {
|
||||
if e, ok := err.(*jwt.ValidationError); ok && e.Errors == jwt.ValidationErrorExpired {
|
||||
// Expired User key needs to be revoked.
|
||||
|
||||
if c.Type != nil && *c.Type == auth.APIKey {
|
||||
return c.toKey(), auth.ErrAPIKeyExpired
|
||||
}
|
||||
@@ -83,18 +84,20 @@ func (svc tokenizer) Parse(token string) (auth.Key, error) {
|
||||
|
||||
func (c claims) toKey() auth.Key {
|
||||
key := auth.Key{
|
||||
ID: c.Id,
|
||||
ID: c.ID,
|
||||
IssuerID: c.IssuerID,
|
||||
Subject: c.Subject,
|
||||
IssuedAt: time.Unix(c.IssuedAt, 0).UTC(),
|
||||
IssuedAt: c.IssuedAt.Time.UTC(),
|
||||
}
|
||||
if c.ExpiresAt != 0 {
|
||||
key.ExpiresAt = time.Unix(c.ExpiresAt, 0).UTC()
|
||||
|
||||
key.ExpiresAt = time.Time{}
|
||||
if c.ExpiresAt != nil && c.ExpiresAt.Time.UTC().Unix() != 0 {
|
||||
key.ExpiresAt = c.ExpiresAt.Time.UTC()
|
||||
}
|
||||
|
||||
// Default type is 0.
|
||||
if c.Type != nil {
|
||||
key.Type = *c.Type
|
||||
key.Type = *(c.Type)
|
||||
}
|
||||
|
||||
return key
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
// LoginKey is temporary User key received on successfull login.
|
||||
// LoginKey is temporary User key received on successful login.
|
||||
LoginKey uint32 = iota
|
||||
// RecoveryKey represents a key for resseting password.
|
||||
RecoveryKey
|
||||
|
||||
+10
-2
@@ -440,7 +440,11 @@ func (gr groupRepository) Assign(ctx context.Context, groupID, groupType string,
|
||||
dbg.UpdatedAt = created
|
||||
|
||||
if _, err := tx.NamedExecContext(ctx, qIns, dbg); err != nil {
|
||||
tx.Rollback()
|
||||
if rollbackErr := tx.Rollback(); rollbackErr != nil {
|
||||
err = errors.Wrap(err, rollbackErr)
|
||||
return errors.Wrap(auth.ErrAssignToGroup, err)
|
||||
}
|
||||
|
||||
pgErr, ok := err.(*pgconn.PgError)
|
||||
if ok {
|
||||
switch pgErr.Code {
|
||||
@@ -479,7 +483,11 @@ func (gr groupRepository) Unassign(ctx context.Context, groupID string, ids ...s
|
||||
}
|
||||
|
||||
if _, err := tx.NamedExecContext(ctx, qDel, dbg); err != nil {
|
||||
tx.Rollback()
|
||||
if rollbackErr := tx.Rollback(); rollbackErr != nil {
|
||||
err = errors.Wrap(rollbackErr, err)
|
||||
return errors.Wrap(auth.ErrAssignToGroup, err)
|
||||
}
|
||||
|
||||
pgErr, ok := err.(*pgconn.PgError)
|
||||
if ok {
|
||||
switch pgErr.Code {
|
||||
|
||||
@@ -154,7 +154,7 @@ func TestGroupRetrieveByID(t *testing.T) {
|
||||
require.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
assert.True(t, retrieved.ID == group1.ID, fmt.Sprintf("Save group, ID: expected %s got %s\n", group1.ID, retrieved.ID))
|
||||
|
||||
// Round to milliseconds as otherwise saving and retriving from DB
|
||||
// Round to milliseconds as otherwise saving and retrieving from DB
|
||||
// adds rounding error.
|
||||
creationTime := time.Now().UTC().Round(time.Millisecond)
|
||||
group2 := auth.Group{
|
||||
|
||||
+2
-2
@@ -183,7 +183,7 @@ func (svc service) AddPolicies(ctx context.Context, token, object string, subjec
|
||||
for _, subjectID := range subjectIDs {
|
||||
for _, relation := range relations {
|
||||
if err := svc.AddPolicy(ctx, PolicyReq{Object: object, Relation: relation, Subject: subjectID}); err != nil {
|
||||
errs = errors.Wrap(fmt.Errorf("cannot add '%s' policy on object '%s' for subject '%s': %s", relation, object, subjectID, err), errs)
|
||||
errs = errors.Wrap(fmt.Errorf("cannot add '%s' policy on object '%s' for subject '%s': %w", relation, object, subjectID, err), errs)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -209,7 +209,7 @@ func (svc service) DeletePolicies(ctx context.Context, token, object string, sub
|
||||
for _, subjectID := range subjectIDs {
|
||||
for _, relation := range relations {
|
||||
if err := svc.DeletePolicy(ctx, PolicyReq{Object: object, Relation: relation, Subject: subjectID}); err != nil {
|
||||
errs = errors.Wrap(fmt.Errorf("cannot delete '%s' policy on object '%s' for subject '%s': %s", relation, object, subjectID, err), errs)
|
||||
errs = errors.Wrap(fmt.Errorf("cannot delete '%s' policy on object '%s' for subject '%s': %w", relation, object, subjectID, err), errs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ const (
|
||||
id = "testID"
|
||||
groupName = "mfx"
|
||||
description = "Description"
|
||||
read = "read"
|
||||
|
||||
memberRelation = "member"
|
||||
authoritiesObj = "authorities"
|
||||
@@ -939,8 +940,8 @@ func TestAssign(t *testing.T) {
|
||||
|
||||
// check access control policies things members.
|
||||
subjectSet := fmt.Sprintf("%s:%s#%s", "members", group.ID, memberRelation)
|
||||
err = svc.Authorize(context.Background(), auth.PolicyReq{Object: mid, Relation: "read", Subject: subjectSet})
|
||||
assert.Nil(t, err, fmt.Sprintf("entites having an access to group %s must have %s policy on %s: %s", group.ID, "read", mid, err))
|
||||
err = svc.Authorize(context.Background(), auth.PolicyReq{Object: mid, Relation: read, Subject: subjectSet})
|
||||
assert.Nil(t, err, fmt.Sprintf("entites having an access to group %s must have %s policy on %s: %s", group.ID, read, mid, err))
|
||||
err = svc.Authorize(context.Background(), auth.PolicyReq{Object: mid, Relation: "write", Subject: subjectSet})
|
||||
assert.Nil(t, err, fmt.Sprintf("entites having an access to group %s must have %s policy on %s: %s", group.ID, "write", mid, err))
|
||||
err = svc.Authorize(context.Background(), auth.PolicyReq{Object: mid, Relation: "delete", Subject: subjectSet})
|
||||
@@ -1082,7 +1083,7 @@ func TestAddPolicies(t *testing.T) {
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
|
||||
tmpID := "tmpid"
|
||||
readPolicy := "read"
|
||||
readPolicy := read
|
||||
writePolicy := "write"
|
||||
deletePolicy := "delete"
|
||||
|
||||
@@ -1167,7 +1168,7 @@ func TestDeletePolicies(t *testing.T) {
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
|
||||
tmpID := "tmpid"
|
||||
readPolicy := "read"
|
||||
readPolicy := read
|
||||
writePolicy := "write"
|
||||
deletePolicy := "delete"
|
||||
memberPolicy := "member"
|
||||
@@ -1253,7 +1254,7 @@ func TestListPolicies(t *testing.T) {
|
||||
_, apiToken, err := svc.Issue(context.Background(), secret, key)
|
||||
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
||||
|
||||
readPolicy := "read"
|
||||
readPolicy := read
|
||||
pageLen := 15
|
||||
|
||||
// Add arbitrary policies to the user.
|
||||
|
||||
@@ -967,7 +967,9 @@ func TestList(t *testing.T) {
|
||||
assert.Equal(t, tc.status, res.StatusCode, fmt.Sprintf("%s: expected status code %d got %d", tc.desc, tc.status, res.StatusCode))
|
||||
var body configPage
|
||||
|
||||
json.NewDecoder(res.Body).Decode(&body)
|
||||
err = json.NewDecoder(res.Body).Decode(&body)
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error while decoding response body: %s", tc.desc, err))
|
||||
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error %s", tc.desc, err))
|
||||
assert.ElementsMatch(t, tc.res.Configs, body.Configs, fmt.Sprintf("%s: expected response '%s' got '%s'", tc.desc, tc.res.Configs, body.Configs))
|
||||
assert.Equal(t, tc.res.Total, body.Total, fmt.Sprintf("%s: expected response total '%d' got '%d'", tc.desc, tc.res.Total, body.Total))
|
||||
@@ -1157,7 +1159,7 @@ func TestBootstrap(t *testing.T) {
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error %s", tc.desc, err))
|
||||
if tc.secure && tc.status == http.StatusOK {
|
||||
body, err = dec(body)
|
||||
assert.Nil(t, err, fmt.Sprintf("%sGot unexpected error: %s\n", tc.desc, err))
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error while decoding body: %s", tc.desc, err))
|
||||
}
|
||||
|
||||
data := strings.Trim(string(body), "\n")
|
||||
|
||||
@@ -83,10 +83,6 @@ func (crm *configRepositoryMock) RetrieveAll(token string, filter bootstrap.Filt
|
||||
|
||||
configs := make([]bootstrap.Config, 0)
|
||||
|
||||
if offset < 0 || limit <= 0 {
|
||||
return bootstrap.ConfigsPage{}
|
||||
}
|
||||
|
||||
first := uint64(offset) + 1
|
||||
last := first + uint64(limit)
|
||||
var state bootstrap.State = emptyState
|
||||
|
||||
@@ -598,7 +598,7 @@ func TestRemoveThing(t *testing.T) {
|
||||
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
|
||||
for i := 0; i < 2; i++ {
|
||||
err := repo.RemoveThing(saved)
|
||||
assert.Nil(t, err, fmt.Sprintf("an unexpected error occured: %s\n", err))
|
||||
assert.Nil(t, err, fmt.Sprintf("an unexpected error occurred: %s\n", err))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ func (es eventStore) Add(ctx context.Context, token string, cfg bootstrap.Config
|
||||
timestamp: time.Now(),
|
||||
}
|
||||
|
||||
es.add(ctx, ev)
|
||||
err = es.add(ctx, ev)
|
||||
|
||||
return saved, err
|
||||
}
|
||||
@@ -74,9 +74,7 @@ func (es eventStore) Update(ctx context.Context, token string, cfg bootstrap.Con
|
||||
timestamp: time.Now(),
|
||||
}
|
||||
|
||||
es.add(ctx, ev)
|
||||
|
||||
return nil
|
||||
return es.add(ctx, ev)
|
||||
}
|
||||
|
||||
func (es eventStore) UpdateCert(ctx context.Context, token, thingKey, clientCert, clientKey, caCert string) error {
|
||||
@@ -94,9 +92,7 @@ func (es eventStore) UpdateConnections(ctx context.Context, token, id string, co
|
||||
timestamp: time.Now(),
|
||||
}
|
||||
|
||||
es.add(ctx, ev)
|
||||
|
||||
return nil
|
||||
return es.add(ctx, ev)
|
||||
}
|
||||
|
||||
func (es eventStore) List(ctx context.Context, token string, filter bootstrap.Filter, offset, limit uint64) (bootstrap.ConfigsPage, error) {
|
||||
@@ -113,9 +109,7 @@ func (es eventStore) Remove(ctx context.Context, token, id string) error {
|
||||
timestamp: time.Now(),
|
||||
}
|
||||
|
||||
es.add(ctx, ev)
|
||||
|
||||
return nil
|
||||
return es.add(ctx, ev)
|
||||
}
|
||||
|
||||
func (es eventStore) Bootstrap(ctx context.Context, externalKey, externalID string, secure bool) (bootstrap.Config, error) {
|
||||
@@ -130,8 +124,7 @@ func (es eventStore) Bootstrap(ctx context.Context, externalKey, externalID stri
|
||||
if err != nil {
|
||||
ev.success = false
|
||||
}
|
||||
|
||||
es.add(ctx, ev)
|
||||
_ = es.add(ctx, ev)
|
||||
|
||||
return cfg, err
|
||||
}
|
||||
@@ -147,9 +140,7 @@ func (es eventStore) ChangeState(ctx context.Context, token, id string, state bo
|
||||
timestamp: time.Now(),
|
||||
}
|
||||
|
||||
es.add(ctx, ev)
|
||||
|
||||
return nil
|
||||
return es.add(ctx, ev)
|
||||
}
|
||||
|
||||
func (es eventStore) RemoveConfigHandler(ctx context.Context, id string) error {
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"github.com/mainflux/mainflux/things"
|
||||
httpapi "github.com/mainflux/mainflux/things/api/things/http"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -92,7 +93,9 @@ func newThingsServer(svc things.Service) *httptest.Server {
|
||||
return httptest.NewServer(mux)
|
||||
}
|
||||
func TestAdd(t *testing.T) {
|
||||
redisClient.FlushAll(context.Background()).Err()
|
||||
err := redisClient.FlushAll(context.Background()).Err()
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
|
||||
users := mocks.NewAuthClient(map[string]string{validToken: email})
|
||||
|
||||
server := newThingsServer(newThingsService(users))
|
||||
@@ -106,6 +109,7 @@ func TestAdd(t *testing.T) {
|
||||
|
||||
invalidConfig := config
|
||||
invalidConfig.MFChannels = []bootstrap.Channel{{ID: "empty"}}
|
||||
invalidConfig.MFChannels = []bootstrap.Channel{{ID: "empty"}}
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
@@ -179,7 +183,8 @@ func TestView(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
redisClient.FlushAll(context.Background()).Err()
|
||||
err := redisClient.FlushAll(context.Background()).Err()
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
|
||||
users := mocks.NewAuthClient(map[string]string{validToken: email})
|
||||
server := newThingsServer(newThingsService(users))
|
||||
@@ -192,8 +197,10 @@ func TestUpdate(t *testing.T) {
|
||||
ch.ID = "2"
|
||||
c.MFChannels = append(c.MFChannels, ch)
|
||||
saved, err := svc.Add(context.Background(), validToken, c)
|
||||
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
|
||||
redisClient.FlushAll(context.Background()).Err()
|
||||
require.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
|
||||
|
||||
err = redisClient.FlushAll(context.Background()).Err()
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
|
||||
modified := saved
|
||||
modified.Content = "new-config"
|
||||
@@ -254,7 +261,8 @@ func TestUpdate(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestUpdateConnections(t *testing.T) {
|
||||
redisClient.FlushAll(context.Background()).Err()
|
||||
err := redisClient.FlushAll(context.Background()).Err()
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
|
||||
users := mocks.NewAuthClient(map[string]string{validToken: email})
|
||||
server := newThingsServer(newThingsService(users))
|
||||
@@ -262,8 +270,9 @@ func TestUpdateConnections(t *testing.T) {
|
||||
svc = producer.NewEventStoreMiddleware(svc, redisClient)
|
||||
|
||||
saved, err := svc.Add(context.Background(), validToken, config)
|
||||
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
|
||||
redisClient.FlushAll(context.Background()).Err()
|
||||
require.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
|
||||
err = redisClient.FlushAll(context.Background()).Err()
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
@@ -336,7 +345,8 @@ func TestList(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRemove(t *testing.T) {
|
||||
redisClient.FlushAll(context.Background()).Err()
|
||||
err := redisClient.FlushAll(context.Background()).Err()
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
|
||||
users := mocks.NewAuthClient(map[string]string{validToken: email})
|
||||
server := newThingsServer(newThingsService(users))
|
||||
@@ -346,8 +356,9 @@ func TestRemove(t *testing.T) {
|
||||
c := config
|
||||
|
||||
saved, err := svc.Add(context.Background(), validToken, c)
|
||||
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
|
||||
redisClient.FlushAll(context.Background()).Err()
|
||||
require.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
|
||||
err = redisClient.FlushAll(context.Background()).Err()
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
@@ -399,7 +410,8 @@ func TestRemove(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBootstrap(t *testing.T) {
|
||||
redisClient.FlushAll(context.Background()).Err()
|
||||
err := redisClient.FlushAll(context.Background()).Err()
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
|
||||
users := mocks.NewAuthClient(map[string]string{validToken: email})
|
||||
server := newThingsServer(newThingsService(users))
|
||||
@@ -409,8 +421,9 @@ func TestBootstrap(t *testing.T) {
|
||||
c := config
|
||||
|
||||
saved, err := svc.Add(context.Background(), validToken, c)
|
||||
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
|
||||
redisClient.FlushAll(context.Background()).Err()
|
||||
require.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
|
||||
err = redisClient.FlushAll(context.Background()).Err()
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
@@ -434,10 +447,10 @@ func TestBootstrap(t *testing.T) {
|
||||
{
|
||||
desc: "bootstrap with an error",
|
||||
externalID: saved.ExternalID,
|
||||
externalKey: "external",
|
||||
externalKey: "external_id",
|
||||
err: bootstrap.ErrExternalKey,
|
||||
event: map[string]interface{}{
|
||||
"external_id": saved.ExternalID,
|
||||
"external_id": "external_id",
|
||||
"success": "0",
|
||||
"timestamp": time.Now().Unix(),
|
||||
"operation": thingBootstrap,
|
||||
@@ -447,7 +460,7 @@ func TestBootstrap(t *testing.T) {
|
||||
|
||||
lastID := "0"
|
||||
for _, tc := range cases {
|
||||
_, err := svc.Bootstrap(context.Background(), tc.externalKey, tc.externalID, false)
|
||||
_, err = svc.Bootstrap(context.Background(), tc.externalKey, tc.externalID, false)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
|
||||
streams := redisClient.XRead(context.Background(), &redis.XReadArgs{
|
||||
@@ -462,13 +475,13 @@ func TestBootstrap(t *testing.T) {
|
||||
event = msg.Values
|
||||
lastID = msg.ID
|
||||
}
|
||||
|
||||
test(t, tc.event, event, tc.desc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestChangeState(t *testing.T) {
|
||||
redisClient.FlushAll(context.Background()).Err()
|
||||
err := redisClient.FlushAll(context.Background()).Err()
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
|
||||
users := mocks.NewAuthClient(map[string]string{validToken: email})
|
||||
server := newThingsServer(newThingsService(users))
|
||||
@@ -478,8 +491,9 @@ func TestChangeState(t *testing.T) {
|
||||
c := config
|
||||
|
||||
saved, err := svc.Add(context.Background(), validToken, c)
|
||||
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
|
||||
redisClient.FlushAll(context.Background()).Err()
|
||||
require.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
|
||||
err = redisClient.FlushAll(context.Background()).Err()
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
@@ -537,14 +551,15 @@ func TestChangeState(t *testing.T) {
|
||||
func test(t *testing.T, expected, actual map[string]interface{}, description string) {
|
||||
if expected != nil && actual != nil {
|
||||
ts1 := expected["timestamp"].(int64)
|
||||
|
||||
ts2, err := strconv.ParseInt(actual["timestamp"].(string), 10, 64)
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: expected to get a valid timestamp, got %s", description, err))
|
||||
require.Nil(t, err, fmt.Sprintf("%s: expected to get a valid timestamp, got %s", description, err))
|
||||
|
||||
val := ts1 == ts2 || ts2 <= ts1+defaultTimout
|
||||
assert.True(t, val, fmt.Sprintf("%s: timestamp is not in valid range", description))
|
||||
|
||||
delete(expected, "timestamp")
|
||||
delete(actual, "timestamp")
|
||||
assert.Equal(t, expected, actual, fmt.Sprintf("%s: expected %v got %v\n", description, expected, actual))
|
||||
assert.Equal(t, expected, actual, fmt.Sprintf("%s: got incorrect event\n", description))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +275,6 @@ func (bs bootstrapService) Bootstrap(ctx context.Context, externalKey, externalI
|
||||
if err != nil {
|
||||
return cfg, errors.Wrap(ErrBootstrap, err)
|
||||
}
|
||||
|
||||
if secure {
|
||||
dec, err := bs.dec(externalKey)
|
||||
if err != nil {
|
||||
@@ -283,7 +282,6 @@ func (bs bootstrapService) Bootstrap(ctx context.Context, externalKey, externalI
|
||||
}
|
||||
externalKey = dec
|
||||
}
|
||||
|
||||
if cfg.ExternalKey != externalKey {
|
||||
return Config{}, ErrExternalKey
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ func (c *certsRepoMock) Save(ctx context.Context, cert certs.Cert) (string, erro
|
||||
switch ok {
|
||||
case false:
|
||||
c.certsByThingID[cert.OwnerID] = map[string][]certs.Cert{
|
||||
cert.ThingID: []certs.Cert{crt},
|
||||
cert.ThingID: {crt},
|
||||
}
|
||||
default:
|
||||
c.certsByThingID[cert.OwnerID][cert.ThingID] = append(c.certsByThingID[cert.OwnerID][cert.ThingID], crt)
|
||||
|
||||
+3
-1
@@ -10,6 +10,8 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const all = "all"
|
||||
|
||||
var cmdChannels = []cobra.Command{
|
||||
{
|
||||
Use: "create <JSON_channel> <user_auth_token>",
|
||||
@@ -60,7 +62,7 @@ var cmdChannels = []cobra.Command{
|
||||
Metadata: metadata,
|
||||
}
|
||||
|
||||
if args[0] == "all" {
|
||||
if args[0] == all {
|
||||
l, err := sdk.Channels(pageMetadata, args[1])
|
||||
if err != nil {
|
||||
logError(err)
|
||||
|
||||
+1
-2
@@ -2,7 +2,6 @@ package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
@@ -19,7 +18,7 @@ type Config struct {
|
||||
|
||||
// read - retrieve config from a file
|
||||
func read(file string) (Config, error) {
|
||||
data, err := ioutil.ReadFile(file)
|
||||
data, err := os.ReadFile(file)
|
||||
c := Config{}
|
||||
if err != nil {
|
||||
return c, errors.New(fmt.Sprintf("failed to read config file: %s", err))
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ var cmdGroups = []cobra.Command{
|
||||
logUsage(cmd.Use)
|
||||
return
|
||||
}
|
||||
if args[0] == "all" {
|
||||
if args[0] == all {
|
||||
if len(args) > 2 {
|
||||
logUsage(cmd.Use)
|
||||
return
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ var cmdThings = []cobra.Command{
|
||||
Limit: uint64(Limit),
|
||||
Metadata: metadata,
|
||||
}
|
||||
if args[0] == "all" {
|
||||
if args[0] == all {
|
||||
l, err := sdk.Things(pageMetadata, args[1])
|
||||
if err != nil {
|
||||
logError(err)
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ var cmdUsers = []cobra.Command{
|
||||
Metadata: metadata,
|
||||
Status: Status,
|
||||
}
|
||||
if args[0] == "all" {
|
||||
if args[0] == all {
|
||||
l, err := sdk.Users(pageMetadata, args[1])
|
||||
if err != nil {
|
||||
logError(err)
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ func (c *client) Handle(msg *messaging.Message) error {
|
||||
return errors.Wrap(ErrOption, err)
|
||||
}
|
||||
opts = append(opts, message.Option{ID: message.Observe, Value: []byte{byte(c.observe)}})
|
||||
opts, n, err = opts.SetObserve(buff, uint32(c.observe))
|
||||
opts, n, err = opts.SetObserve(buff, c.observe)
|
||||
if err == message.ErrTooSmall {
|
||||
buff = append(buff, make([]byte, n)...)
|
||||
opts, _, err = opts.SetObserve(buff, uint32(c.observe))
|
||||
|
||||
@@ -15,7 +15,7 @@ require (
|
||||
github.com/go-zoo/bone v1.3.0
|
||||
github.com/gocql/gocql v1.2.1
|
||||
github.com/gofrs/uuid v4.3.0+incompatible
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/gopcua/opcua v0.1.6
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
|
||||
@@ -217,8 +217,8 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
|
||||
+5
-5
@@ -47,29 +47,29 @@ func New(out io.Writer, levelText string) (Logger, error) {
|
||||
|
||||
func (l logger) Debug(msg string) {
|
||||
if Debug.isAllowed(l.level) {
|
||||
l.kitLogger.Log("level", Debug.String(), "message", msg)
|
||||
_ = l.kitLogger.Log("level", Debug.String(), "message", msg)
|
||||
}
|
||||
}
|
||||
|
||||
func (l logger) Info(msg string) {
|
||||
if Info.isAllowed(l.level) {
|
||||
l.kitLogger.Log("level", Info.String(), "message", msg)
|
||||
_ = l.kitLogger.Log("level", Info.String(), "message", msg)
|
||||
}
|
||||
}
|
||||
|
||||
func (l logger) Warn(msg string) {
|
||||
if Warn.isAllowed(l.level) {
|
||||
l.kitLogger.Log("level", Warn.String(), "message", msg)
|
||||
_ = l.kitLogger.Log("level", Warn.String(), "message", msg)
|
||||
}
|
||||
}
|
||||
|
||||
func (l logger) Error(msg string) {
|
||||
if Error.isAllowed(l.level) {
|
||||
l.kitLogger.Log("level", Error.String(), "message", msg)
|
||||
_ = l.kitLogger.Log("level", Error.String(), "message", msg)
|
||||
}
|
||||
}
|
||||
|
||||
func (l logger) Fatal(msg string) {
|
||||
l.kitLogger.Log("fatal", msg)
|
||||
_ = l.kitLogger.Log("fatal", msg)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
+1
-1
@@ -110,7 +110,7 @@ func (as *adapterService) Publish(ctx context.Context, m *Message) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
payload = []byte(jo)
|
||||
payload = jo
|
||||
}
|
||||
|
||||
// Publish on Mainflux Message broker
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/mainflux/mainflux/lora/mocks"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -40,19 +41,19 @@ func TestPublish(t *testing.T) {
|
||||
svc := newService()
|
||||
|
||||
err := svc.CreateChannel(context.Background(), chanID, appID)
|
||||
assert.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
|
||||
err = svc.CreateThing(context.Background(), thingID, devEUI)
|
||||
assert.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
|
||||
err = svc.ConnectThing(context.Background(), chanID, thingID)
|
||||
assert.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
|
||||
err = svc.CreateChannel(context.Background(), chanID2, appID2)
|
||||
assert.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
|
||||
err = svc.CreateThing(context.Background(), thingID2, devEUI2)
|
||||
assert.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
|
||||
msgBase64 := base64.StdEncoding.EncodeToString([]byte(msg))
|
||||
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ type RxInfo []struct {
|
||||
// DataRate lora data rate
|
||||
type DataRate struct {
|
||||
Modulation string `json:"modulation"`
|
||||
Bandwith float64 `json:"bandwith"`
|
||||
Bandwidth float64 `json:"bandwidth"`
|
||||
SpreadFactor int64 `json:"spreadFactor"`
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -54,5 +54,7 @@ func (b broker) handleMsg(c mqtt.Client, msg mqtt.Message) {
|
||||
return
|
||||
}
|
||||
|
||||
b.svc.Publish(context.Background(), &m)
|
||||
if err := b.svc.Publish(context.Background(), &m); err != nil {
|
||||
b.logger.Error(fmt.Sprintf("got error while publishing messages: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,11 +33,7 @@ func (mr *routerMap) Save(ctx context.Context, mfxID, loraID string) error {
|
||||
}
|
||||
|
||||
lkey := fmt.Sprintf("%s:%s", mr.prefix, loraID)
|
||||
if err := mr.client.Set(ctx, lkey, mfxID, 0).Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return mr.client.Set(ctx, lkey, mfxID, 0).Err()
|
||||
}
|
||||
|
||||
func (mr *routerMap) Get(ctx context.Context, id string) (string, error) {
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@
|
||||
|
||||
// Package redis contains cache implementations using Redis as
|
||||
// the underlying database.
|
||||
package redis
|
||||
package redis
|
||||
|
||||
@@ -52,11 +52,7 @@ func (es eventStore) storeEvent(clientID, eventType string) error {
|
||||
Values: event.Encode(),
|
||||
}
|
||||
|
||||
if err := es.client.XAdd(context.Background(), record).Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return es.client.XAdd(context.Background(), record).Err()
|
||||
}
|
||||
|
||||
// Connect issues event on MQTT CONNECT
|
||||
|
||||
+5
-2
@@ -28,15 +28,18 @@ type Node struct {
|
||||
NodeID string
|
||||
}
|
||||
|
||||
// Save stores a successfull subscription
|
||||
// Save stores a successful subscription
|
||||
func Save(serverURI, nodeID string) error {
|
||||
file, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, os.ModePerm)
|
||||
if err != nil {
|
||||
return errors.Wrap(errWriteFile, err)
|
||||
}
|
||||
csvWriter := csv.NewWriter(file)
|
||||
csvWriter.Write([]string{serverURI, nodeID})
|
||||
err = csvWriter.Write([]string{serverURI, nodeID})
|
||||
csvWriter.Flush()
|
||||
if err != nil {
|
||||
return errors.Wrap(errWriteFile, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -111,7 +111,11 @@ func (c client) Subscribe(ctx context.Context, cfg opcua.Config) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(errFailedSub, err)
|
||||
}
|
||||
defer sub.Cancel()
|
||||
defer func() {
|
||||
if err = sub.Cancel(); err != nil {
|
||||
c.logger.Error(fmt.Sprintf("subscription could not be cancelled: %s", err))
|
||||
}
|
||||
}()
|
||||
|
||||
if err := c.runHandler(ctx, sub, cfg.ServerURI, cfg.NodeID); err != nil {
|
||||
c.logger.Warn(fmt.Sprintf("Unsubscribed from OPC-UA node %s.%s: %s", cfg.ServerURI, cfg.NodeID, err))
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ func (c client) Identify(ctx context.Context, thingKey string) (string, error) {
|
||||
thingID, err := c.redisClient.Get(ctx, tkey).Result()
|
||||
if err != nil {
|
||||
t := &mainflux.Token{
|
||||
Value: string(thingKey),
|
||||
Value: thingKey,
|
||||
}
|
||||
|
||||
thid, err := c.thingsClient.Identify(context.TODO(), t)
|
||||
|
||||
@@ -53,11 +53,7 @@ func (pub *publisher) Publish(ctx context.Context, topic string, msg *messaging.
|
||||
subject = fmt.Sprintf("%s.%s", subject, msg.Subtopic)
|
||||
}
|
||||
|
||||
if err := pub.conn.Publish(subject, data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return pub.conn.Publish(subject, data)
|
||||
}
|
||||
|
||||
func (pub *publisher) Close() error {
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ type keyReq struct {
|
||||
const keysEndpoint = "keys"
|
||||
|
||||
const (
|
||||
// LoginKey is temporary User key received on successfull login.
|
||||
// LoginKey is temporary User key received on successful login.
|
||||
LoginKey uint32 = iota
|
||||
// RecoveryKey represents a key for resseting password.
|
||||
RecoveryKey
|
||||
|
||||
@@ -733,7 +733,9 @@ func TestReadAll(t *testing.T) {
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error %s", tc.desc, err))
|
||||
|
||||
var page pageRes
|
||||
json.NewDecoder(res.Body).Decode(&page)
|
||||
err = json.NewDecoder(res.Body).Decode(&page)
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error while decoding response body: %s", tc.desc, err))
|
||||
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error %s", tc.desc, err))
|
||||
assert.Equal(t, tc.status, res.StatusCode, fmt.Sprintf("%s: expected %d got %d", tc.desc, tc.status, res.StatusCode))
|
||||
assert.Equal(t, tc.res.Total, page.Total, fmt.Sprintf("%s: expected %d got %d", tc.desc, tc.res.Total, page.Total))
|
||||
|
||||
@@ -74,10 +74,9 @@ func (cr cassandraRepository) ReadAll(chanID string, rpm readers.PageMetadata) (
|
||||
case defTable:
|
||||
for scanner.Next() {
|
||||
var msg senml.Message
|
||||
err := scanner.Scan(&msg.Channel, &msg.Subtopic, &msg.Publisher, &msg.Protocol,
|
||||
if err := scanner.Scan(&msg.Channel, &msg.Subtopic, &msg.Publisher, &msg.Protocol,
|
||||
&msg.Name, &msg.Unit, &msg.Value, &msg.StringValue, &msg.BoolValue,
|
||||
&msg.DataValue, &msg.Sum, &msg.Time, &msg.UpdateTime)
|
||||
if err != nil {
|
||||
&msg.DataValue, &msg.Sum, &msg.Time, &msg.UpdateTime); err != nil {
|
||||
if e, ok := err.(gocql.RequestError); ok {
|
||||
if e.Code() == undefinedTableCode {
|
||||
return readers.MessagesPage{}, nil
|
||||
@@ -90,8 +89,7 @@ func (cr cassandraRepository) ReadAll(chanID string, rpm readers.PageMetadata) (
|
||||
default:
|
||||
for scanner.Next() {
|
||||
var msg jsonMessage
|
||||
err := scanner.Scan(&msg.Channel, &msg.Subtopic, &msg.Publisher, &msg.Protocol, &msg.Created, &msg.Payload)
|
||||
if err != nil {
|
||||
if err := scanner.Scan(&msg.Channel, &msg.Subtopic, &msg.Publisher, &msg.Protocol, &msg.Created, &msg.Payload); err != nil {
|
||||
if e, ok := err.(gocql.RequestError); ok {
|
||||
if e.Code() == undefinedTableCode {
|
||||
return readers.MessagesPage{}, nil
|
||||
@@ -128,7 +126,9 @@ func buildQuery(chanID string, rpm readers.PageMetadata) (string, []interface{})
|
||||
if err != nil {
|
||||
return condCQL, vals
|
||||
}
|
||||
json.Unmarshal(meta, &query)
|
||||
if err := json.Unmarshal(meta, &query); err != nil {
|
||||
return condCQL, vals
|
||||
}
|
||||
|
||||
for name, val := range query {
|
||||
switch name {
|
||||
|
||||
@@ -52,6 +52,7 @@ func TestReadSenml(t *testing.T) {
|
||||
})
|
||||
require.Nil(t, err, fmt.Sprintf("failed to connect to Cassandra: %s", err))
|
||||
defer session.Close()
|
||||
|
||||
err = casClient.InitDB(session, cwriter.Table)
|
||||
require.Nil(t, err, fmt.Sprintf("failed to initialize to Cassandra: %s", err))
|
||||
writer := cwriter.New(session)
|
||||
|
||||
@@ -119,8 +119,8 @@ func (repo *influxRepository) count(measurement, condition string, timeRange str
|
||||
measurement,
|
||||
condition)
|
||||
queryAPI := repo.client.QueryAPI(repo.cfg.Org)
|
||||
resp, err := queryAPI.Query(context.Background(), cmd)
|
||||
|
||||
resp, err := queryAPI.Query(context.Background(), cmd)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -168,7 +168,7 @@ func fmtCondition(chanID string, rpm readers.PageMetadata) (string, string) {
|
||||
toValue := int64(value.(float64) * 1e9)
|
||||
to = fmt.Sprintf(`, stop: time(v: %d )`, toValue)
|
||||
}
|
||||
// timeRange returned seperately because
|
||||
// timeRange returned separately because
|
||||
// in FluxQL time range must be at the
|
||||
// beginning of the query.
|
||||
timeRange = fmt.Sprintf(`|> range(%s %s)`, from, to)
|
||||
|
||||
@@ -39,8 +39,13 @@ func (repo *messageRepositoryMock) ReadAll(chanID string, rpm readers.PageMetada
|
||||
}
|
||||
|
||||
var query map[string]interface{}
|
||||
meta, _ := json.Marshal(rpm)
|
||||
json.Unmarshal(meta, &query)
|
||||
meta, err := json.Marshal(rpm)
|
||||
if err != nil {
|
||||
return readers.MessagesPage{}, err
|
||||
}
|
||||
if err := json.Unmarshal(meta, &query); err != nil {
|
||||
return readers.MessagesPage{}, err
|
||||
}
|
||||
|
||||
var msgs []readers.Message
|
||||
for _, m := range repo.messages[chanID] {
|
||||
|
||||
@@ -101,7 +101,9 @@ func fmtCondition(chanID string, rpm readers.PageMetadata) bson.D {
|
||||
if err != nil {
|
||||
return filter
|
||||
}
|
||||
json.Unmarshal(meta, &query)
|
||||
if err := json.Unmarshal(meta, &query); err != nil {
|
||||
return filter
|
||||
}
|
||||
|
||||
for name, value := range query {
|
||||
switch name {
|
||||
|
||||
@@ -123,7 +123,9 @@ func fmtCondition(chanID string, rpm readers.PageMetadata) string {
|
||||
if err != nil {
|
||||
return condition
|
||||
}
|
||||
json.Unmarshal(meta, &query)
|
||||
if err := json.Unmarshal(meta, &query); err != nil {
|
||||
return condition
|
||||
}
|
||||
|
||||
for name := range query {
|
||||
switch name {
|
||||
|
||||
@@ -121,7 +121,9 @@ func fmtCondition(chanID string, rpm readers.PageMetadata) string {
|
||||
if err != nil {
|
||||
return condition
|
||||
}
|
||||
json.Unmarshal(meta, &query)
|
||||
if err := json.Unmarshal(meta, &query); err != nil {
|
||||
return condition
|
||||
}
|
||||
|
||||
for name := range query {
|
||||
switch name {
|
||||
|
||||
+3
-2
@@ -4,6 +4,7 @@ GO_VERSION=1.19.4
|
||||
PROTOC_VERSION=21.12
|
||||
PROTOC_GEN_VERSION=v1.28.1
|
||||
PROTOC_GRPC_VERSION=v1.2.0
|
||||
GOLANGCI_LINT_VERSION=v1.52.1
|
||||
|
||||
function version_gt() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; }
|
||||
|
||||
@@ -71,7 +72,7 @@ setup_mf() {
|
||||
|
||||
setup_lint() {
|
||||
# binary will be $(go env GOBIN)/golangci-lint
|
||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOBIN) v1.46.2
|
||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOBIN) $GOLANGCI_LINT_VERSION
|
||||
|
||||
}
|
||||
|
||||
@@ -85,7 +86,7 @@ setup() {
|
||||
|
||||
run_test() {
|
||||
echo "Running lint..."
|
||||
golangci-lint run --no-config --disable-all --enable gosimple --enable govet --enable unused --enable deadcode --timeout 3m
|
||||
golangci-lint run --no-config --disable-all --enable gosimple --enable errcheck --enable govet --enable unused --enable goconst --timeout 3m
|
||||
echo "Running tests..."
|
||||
echo "" > coverage.txt
|
||||
for d in $(go list ./... | grep -v 'vendor\|cmd'); do
|
||||
|
||||
@@ -100,7 +100,9 @@ func TestCanAccessByID(t *testing.T) {
|
||||
chs, err := svc.CreateChannels(context.Background(), token, channel)
|
||||
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
ch := chs[0]
|
||||
svc.Connect(context.Background(), token, []string{ch.ID}, []string{th2.ID})
|
||||
|
||||
err = svc.Connect(context.Background(), token, []string{ch.ID}, []string{th2.ID})
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error while connecting to service: %s", err))
|
||||
|
||||
usersAddr := fmt.Sprintf("localhost:%d", port)
|
||||
conn, err := grpc.Dial(usersAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
|
||||
@@ -5,6 +5,7 @@ package grpc_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"testing"
|
||||
@@ -28,17 +29,31 @@ const (
|
||||
var svc things.Service
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
startServer()
|
||||
code := m.Run()
|
||||
os.Exit(code)
|
||||
}
|
||||
serverErr := make(chan error)
|
||||
|
||||
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||
if err != nil {
|
||||
log.Fatalf("got unexpected error while creating new listerner: %s", err)
|
||||
}
|
||||
|
||||
func startServer() {
|
||||
svc = newService(map[string]string{token: email})
|
||||
listener, _ := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||
server := grpc.NewServer()
|
||||
mainflux.RegisterThingsServiceServer(server, grpcapi.NewServer(mocktracer.New(), svc))
|
||||
go server.Serve(listener)
|
||||
|
||||
// Start gRPC server in detached mode.
|
||||
go func() {
|
||||
serverErr <- server.Serve(listener)
|
||||
}()
|
||||
|
||||
code := m.Run()
|
||||
|
||||
server.GracefulStop()
|
||||
err = <-serverErr
|
||||
if err != nil {
|
||||
log.Fatalln("gPRC Server Terminated : ", err)
|
||||
}
|
||||
close(serverErr)
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
func newService(tokens map[string]string) things.Service {
|
||||
|
||||
@@ -29,17 +29,20 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
contentType = "application/json"
|
||||
email = "user@example.com"
|
||||
adminEmail = "admin@example.com"
|
||||
token = "token"
|
||||
wrongValue = "wrong_value"
|
||||
wrongID = 0
|
||||
maxNameSize = 1024
|
||||
nameKey = "name"
|
||||
ascKey = "asc"
|
||||
descKey = "desc"
|
||||
prefix = "fe6b4e92-cc98-425e-b0aa-"
|
||||
contentType = "application/json"
|
||||
email = "user@example.com"
|
||||
adminEmail = "admin@example.com"
|
||||
otherExampleEmail = "other_user@example.com"
|
||||
token = "token"
|
||||
otherExampleToken = "other_token"
|
||||
wrongValue = "wrong_value"
|
||||
thingKey = "key"
|
||||
wrongID = 0
|
||||
maxNameSize = 1024
|
||||
nameKey = "name"
|
||||
ascKey = "asc"
|
||||
descKey = "desc"
|
||||
prefix = "fe6b4e92-cc98-425e-b0aa-"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -116,7 +119,7 @@ func TestCreateThing(t *testing.T) {
|
||||
defer ts.Close()
|
||||
|
||||
th := thing
|
||||
th.Key = "key"
|
||||
th.Key = thingKey
|
||||
data := toJSON(th)
|
||||
|
||||
th.Name = invalidName
|
||||
@@ -956,12 +959,14 @@ func TestListThings(t *testing.T) {
|
||||
token: tc.auth,
|
||||
}
|
||||
res, err := req.make()
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: got unexpected error %s", tc.desc, err))
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error %s", tc.desc, err))
|
||||
|
||||
var data thingsPageRes
|
||||
json.NewDecoder(res.Body).Decode(&data)
|
||||
err = json.NewDecoder(res.Body).Decode(&data)
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error %s", tc.desc, err))
|
||||
|
||||
assert.Equal(t, tc.statusCode, res.StatusCode, fmt.Sprintf("%s: expected status code %d got %d", tc.desc, tc.statusCode, res.StatusCode))
|
||||
assert.ElementsMatch(t, tc.res, data.Things, fmt.Sprintf("%s: got incorrect list of things from response body", tc.desc))
|
||||
assert.ElementsMatch(t, tc.res, data.Things, fmt.Sprintf("%s: expected body %v got %v", tc.desc, tc.res, data.Things))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1153,12 +1158,14 @@ func TestSearchThings(t *testing.T) {
|
||||
body: strings.NewReader(tc.req),
|
||||
}
|
||||
res, err := req.make()
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: got unexpected error %s", tc.desc, err))
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error %s", tc.desc, err))
|
||||
|
||||
var data thingsPageRes
|
||||
json.NewDecoder(res.Body).Decode(&data)
|
||||
err = json.NewDecoder(res.Body).Decode(&data)
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error %s", tc.desc, err))
|
||||
|
||||
assert.Equal(t, tc.statusCode, res.StatusCode, fmt.Sprintf("%s: expected status code %d got %d", tc.desc, tc.statusCode, res.StatusCode))
|
||||
assert.ElementsMatch(t, tc.res, data.Things, fmt.Sprintf("%s: got incorrect list of things from response body", tc.desc))
|
||||
assert.ElementsMatch(t, tc.res, data.Things, fmt.Sprintf("%s: expected body %v got %v", tc.desc, tc.res, data.Things))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1337,12 +1344,14 @@ func TestListThingsByChannel(t *testing.T) {
|
||||
token: tc.auth,
|
||||
}
|
||||
res, err := req.make()
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: got unexpected error %s", tc.desc, err))
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error %s", tc.desc, err))
|
||||
|
||||
var data thingsPageRes
|
||||
json.NewDecoder(res.Body).Decode(&data)
|
||||
err = json.NewDecoder(res.Body).Decode(&data)
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error %s", tc.desc, err))
|
||||
|
||||
assert.Equal(t, tc.statusCode, res.StatusCode, fmt.Sprintf("%s: expected status code %d got %d", tc.desc, tc.statusCode, res.StatusCode))
|
||||
assert.ElementsMatch(t, tc.res, data.Things, fmt.Sprintf("%s: got incorrect list of things from response body", tc.desc))
|
||||
assert.ElementsMatch(t, tc.res, data.Things, fmt.Sprintf("%s: expected body %v got %v", tc.desc, tc.res, data.Things))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1725,7 +1734,8 @@ func TestViewChannel(t *testing.T) {
|
||||
ths, err := svc.CreateThings(context.Background(), token, thing)
|
||||
require.Nil(t, err, fmt.Sprintf("got unexpected error: %s\n", err))
|
||||
th := ths[0]
|
||||
svc.Connect(context.Background(), token, []string{sch.ID}, []string{th.ID})
|
||||
err = svc.Connect(context.Background(), token, []string{sch.ID}, []string{th.ID})
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error when connecting to service: %s", err))
|
||||
|
||||
data := toJSON(channelRes{
|
||||
ID: sch.ID,
|
||||
@@ -1815,7 +1825,8 @@ func TestListChannels(t *testing.T) {
|
||||
ths, err := svc.CreateThings(context.Background(), token, thing)
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
th := ths[0]
|
||||
svc.Connect(context.Background(), token, []string{ch.ID}, []string{th.ID})
|
||||
err = svc.Connect(context.Background(), token, []string{ch.ID}, []string{th.ID})
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error while connecting to service: %s", err))
|
||||
|
||||
channels = append(channels, channelRes{
|
||||
ID: ch.ID,
|
||||
@@ -2006,9 +2017,11 @@ func TestListChannels(t *testing.T) {
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: got unexpected error %s", tc.desc, err))
|
||||
|
||||
var body channelsPageRes
|
||||
json.NewDecoder(res.Body).Decode(&body)
|
||||
err = json.NewDecoder(res.Body).Decode(&body)
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error while deconding response body: %s", tc.desc, err))
|
||||
|
||||
assert.Equal(t, tc.statusCode, res.StatusCode, fmt.Sprintf("%s: expected status code %d got %d", tc.desc, tc.statusCode, res.StatusCode))
|
||||
assert.ElementsMatch(t, tc.res, body.Channels, fmt.Sprintf("%s: got incorrect list of channels from response body", tc.desc))
|
||||
assert.ElementsMatch(t, tc.res, body.Channels, fmt.Sprintf("%s: expected body %v got %v", tc.desc, tc.res, body.Channels))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2186,9 +2199,11 @@ func TestListChannelsByThing(t *testing.T) {
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: got unexpected error %s", tc.desc, err))
|
||||
|
||||
var body channelsPageRes
|
||||
json.NewDecoder(res.Body).Decode(&body)
|
||||
err = json.NewDecoder(res.Body).Decode(&body)
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error while decoding response body: %s", tc.desc, err))
|
||||
|
||||
assert.Equal(t, tc.statusCode, res.StatusCode, fmt.Sprintf("%s: expected status code %d got %d", tc.desc, tc.statusCode, res.StatusCode))
|
||||
assert.ElementsMatch(t, tc.res, body.Channels, fmt.Sprintf("%s: got incorrect list of channels from response body", tc.desc))
|
||||
assert.ElementsMatch(t, tc.res, body.Channels, fmt.Sprintf("%s: expected body %v got %v", tc.desc, tc.res, body.Channels))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2252,8 +2267,8 @@ func TestRemoveChannel(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnect(t *testing.T) {
|
||||
otherToken := "other_token"
|
||||
otherEmail := "other_user@example.com"
|
||||
otherToken := otherExampleToken
|
||||
otherEmail := otherExampleEmail
|
||||
svc := newService(map[string]string{
|
||||
token: email,
|
||||
otherToken: otherEmail,
|
||||
@@ -2348,8 +2363,8 @@ func TestConnect(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCreateConnections(t *testing.T) {
|
||||
otherToken := "other_token"
|
||||
otherEmail := "other_user@example.com"
|
||||
otherToken := otherExampleToken
|
||||
otherEmail := otherExampleEmail
|
||||
svc := newService(map[string]string{
|
||||
token: email,
|
||||
otherToken: otherEmail,
|
||||
@@ -2537,8 +2552,8 @@ func TestCreateConnections(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDisconnectList(t *testing.T) {
|
||||
otherToken := "other_token"
|
||||
otherEmail := "other_user@example.com"
|
||||
otherToken := otherExampleToken
|
||||
otherEmail := otherExampleEmail
|
||||
svc := newService(map[string]string{
|
||||
token: email,
|
||||
otherToken: otherEmail,
|
||||
@@ -2730,8 +2745,8 @@ func TestDisconnectList(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDisconnnect(t *testing.T) {
|
||||
otherToken := "other_token"
|
||||
otherEmail := "other_user@example.com"
|
||||
otherToken := otherExampleToken
|
||||
otherEmail := otherExampleEmail
|
||||
svc := newService(map[string]string{
|
||||
token: email,
|
||||
otherToken: otherEmail,
|
||||
@@ -2741,9 +2756,13 @@ func TestDisconnnect(t *testing.T) {
|
||||
|
||||
ths, _ := svc.CreateThings(context.Background(), token, thing)
|
||||
th1 := ths[0]
|
||||
|
||||
chs, _ := svc.CreateChannels(context.Background(), token, channel)
|
||||
ch1 := chs[0]
|
||||
svc.Connect(context.Background(), token, []string{ch1.ID}, []string{th1.ID})
|
||||
|
||||
err := svc.Connect(context.Background(), token, []string{ch1.ID}, []string{th1.ID})
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error while connecting to service: %s", err))
|
||||
|
||||
chs, _ = svc.CreateChannels(context.Background(), otherToken, channel)
|
||||
ch2 := chs[0]
|
||||
|
||||
|
||||
@@ -80,9 +80,6 @@ func (crm *channelRepositoryMock) RetrieveByID(_ context.Context, owner, id stri
|
||||
}
|
||||
|
||||
func (crm *channelRepositoryMock) RetrieveAll(_ context.Context, owner string, pm things.PageMetadata) (things.ChannelsPage, error) {
|
||||
if pm.Limit < 0 {
|
||||
return things.ChannelsPage{}, nil
|
||||
}
|
||||
if pm.Limit == 0 {
|
||||
pm.Limit = 10
|
||||
}
|
||||
|
||||
+10
-8
@@ -12,6 +12,8 @@ import (
|
||||
)
|
||||
|
||||
const uuidLen = 36
|
||||
const asc = "asc"
|
||||
const desc = "desc"
|
||||
|
||||
// Since mocks will store data in map, and they need to resemble the real
|
||||
// identifiers as much as possible, a key will be created as combination of
|
||||
@@ -24,23 +26,23 @@ func key(owner string, id string) string {
|
||||
func sortThings(pm things.PageMetadata, ths []things.Thing) []things.Thing {
|
||||
switch pm.Order {
|
||||
case "name":
|
||||
if pm.Dir == "asc" {
|
||||
if pm.Dir == asc {
|
||||
sort.SliceStable(ths, func(i, j int) bool {
|
||||
return ths[i].Name < ths[j].Name
|
||||
})
|
||||
}
|
||||
if pm.Dir == "desc" {
|
||||
if pm.Dir == desc {
|
||||
sort.SliceStable(ths, func(i, j int) bool {
|
||||
return ths[i].Name > ths[j].Name
|
||||
})
|
||||
}
|
||||
case "id":
|
||||
if pm.Dir == "asc" {
|
||||
if pm.Dir == asc {
|
||||
sort.SliceStable(ths, func(i, j int) bool {
|
||||
return ths[i].ID < ths[j].ID
|
||||
})
|
||||
}
|
||||
if pm.Dir == "desc" {
|
||||
if pm.Dir == desc {
|
||||
sort.SliceStable(ths, func(i, j int) bool {
|
||||
return ths[i].ID > ths[j].ID
|
||||
})
|
||||
@@ -57,23 +59,23 @@ func sortThings(pm things.PageMetadata, ths []things.Thing) []things.Thing {
|
||||
func sortChannels(pm things.PageMetadata, chs []things.Channel) []things.Channel {
|
||||
switch pm.Order {
|
||||
case "name":
|
||||
if pm.Dir == "asc" {
|
||||
if pm.Dir == asc {
|
||||
sort.SliceStable(chs, func(i, j int) bool {
|
||||
return chs[i].Name < chs[j].Name
|
||||
})
|
||||
}
|
||||
if pm.Dir == "desc" {
|
||||
if pm.Dir == desc {
|
||||
sort.SliceStable(chs, func(i, j int) bool {
|
||||
return chs[i].Name > chs[j].Name
|
||||
})
|
||||
}
|
||||
case "id":
|
||||
if pm.Dir == "asc" {
|
||||
if pm.Dir == asc {
|
||||
sort.SliceStable(chs, func(i, j int) bool {
|
||||
return chs[i].ID < chs[j].ID
|
||||
})
|
||||
}
|
||||
if pm.Dir == "desc" {
|
||||
if pm.Dir == desc {
|
||||
sort.SliceStable(chs, func(i, j int) bool {
|
||||
return chs[i].ID > chs[j].ID
|
||||
})
|
||||
|
||||
@@ -117,10 +117,6 @@ func (trm *thingRepositoryMock) RetrieveAll(_ context.Context, owner string, pm
|
||||
trm.mu.Lock()
|
||||
defer trm.mu.Unlock()
|
||||
|
||||
if pm.Limit < 0 {
|
||||
return things.Page{}, nil
|
||||
}
|
||||
|
||||
first := uint64(pm.Offset) + 1
|
||||
last := first + uint64(pm.Limit)
|
||||
|
||||
|
||||
+23
-10
@@ -20,6 +20,8 @@ import (
|
||||
|
||||
var _ things.ChannelRepository = (*channelRepository)(nil)
|
||||
|
||||
const name = "name"
|
||||
|
||||
type channelRepository struct {
|
||||
db Database
|
||||
}
|
||||
@@ -52,7 +54,9 @@ func (cr channelRepository) Save(ctx context.Context, channels ...things.Channel
|
||||
|
||||
_, err = tx.NamedExecContext(ctx, q, dbch)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
if err := tx.Rollback(); err != nil {
|
||||
return []things.Channel{}, errors.Wrap(errors.ErrCreateEntity, err)
|
||||
}
|
||||
pgErr, ok := err.(*pgconn.PgError)
|
||||
if ok {
|
||||
switch pgErr.Code {
|
||||
@@ -64,6 +68,7 @@ func (cr channelRepository) Save(ctx context.Context, channels ...things.Channel
|
||||
return []things.Channel{}, errors.Wrap(errors.ErrMalformedEntity, err)
|
||||
}
|
||||
}
|
||||
|
||||
return []things.Channel{}, errors.Wrap(errors.ErrCreateEntity, err)
|
||||
}
|
||||
}
|
||||
@@ -291,8 +296,9 @@ func (cr channelRepository) Remove(ctx context.Context, owner, id string) error
|
||||
Owner: owner,
|
||||
}
|
||||
q := `DELETE FROM channels WHERE id = :id AND owner = :owner`
|
||||
cr.db.NamedExecContext(ctx, q, dbch)
|
||||
return nil
|
||||
|
||||
_, err := cr.db.NamedExecContext(ctx, q, dbch)
|
||||
return err
|
||||
}
|
||||
|
||||
func (cr channelRepository) Connect(ctx context.Context, owner string, chIDs, thIDs []string) error {
|
||||
@@ -314,7 +320,10 @@ func (cr channelRepository) Connect(ctx context.Context, owner string, chIDs, th
|
||||
|
||||
_, err := tx.NamedExecContext(ctx, q, dbco)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
if err := tx.Rollback(); err != nil {
|
||||
return errors.Wrap(things.ErrConnect, err)
|
||||
}
|
||||
|
||||
pgErr, ok := err.(*pgconn.PgError)
|
||||
if ok {
|
||||
switch pgErr.Code {
|
||||
@@ -357,7 +366,11 @@ func (cr channelRepository) Disconnect(ctx context.Context, owner string, chIDs,
|
||||
|
||||
res, err := tx.NamedExecContext(ctx, q, dbco)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
err = tx.Rollback()
|
||||
if err != nil {
|
||||
return errors.Wrap(things.ErrConnect, err)
|
||||
}
|
||||
|
||||
pgErr, ok := err.(*pgconn.PgError)
|
||||
if ok {
|
||||
switch pgErr.Code {
|
||||
@@ -428,13 +441,13 @@ type dbMetadata map[string]interface{}
|
||||
// If error occurs on casting data then m points to empty metadata.
|
||||
func (m *dbMetadata) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
m = nil
|
||||
*m = dbMetadata{}
|
||||
return nil
|
||||
}
|
||||
|
||||
b, ok := value.([]byte)
|
||||
if !ok {
|
||||
m = &dbMetadata{}
|
||||
*m = dbMetadata{}
|
||||
return errors.ErrScanMetadata
|
||||
}
|
||||
|
||||
@@ -494,8 +507,8 @@ func getNameQuery(name string) (string, string) {
|
||||
|
||||
func getOrderQuery(order string) string {
|
||||
switch order {
|
||||
case "name":
|
||||
return "name"
|
||||
case name:
|
||||
return name
|
||||
default:
|
||||
return "id"
|
||||
}
|
||||
@@ -503,7 +516,7 @@ func getOrderQuery(order string) string {
|
||||
|
||||
func getConnOrderQuery(order string, level string) string {
|
||||
switch order {
|
||||
case "name":
|
||||
case name:
|
||||
return level + ".name"
|
||||
default:
|
||||
return level + ".id"
|
||||
|
||||
@@ -78,8 +78,7 @@ func TestChannelsSave(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
resp, err := channelRepo.Save(context.Background(), tc.channels...)
|
||||
assert.Equal(t, tc.response, resp, fmt.Sprintf("%s: got incorrect list of channels from Save()", tc.desc))
|
||||
_, err := channelRepo.Save(context.Background(), tc.channels...)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
}
|
||||
}
|
||||
@@ -172,7 +171,9 @@ func TestSingleChannelRetrieval(t *testing.T) {
|
||||
}
|
||||
chs, _ := chanRepo.Save(context.Background(), ch)
|
||||
ch.ID = chs[0].ID
|
||||
chanRepo.Connect(context.Background(), email, []string{ch.ID}, []string{th.ID})
|
||||
|
||||
err = chanRepo.Connect(context.Background(), email, []string{ch.ID}, []string{th.ID})
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error while connecting to service: %s", err))
|
||||
|
||||
nonexistentChanID, err := idProvider.ID()
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
@@ -256,7 +257,8 @@ func TestMultiChannelRetrieval(t *testing.T) {
|
||||
ch.Name = name
|
||||
}
|
||||
|
||||
chanRepo.Save(context.Background(), ch)
|
||||
_, err = chanRepo.Save(context.Background(), ch)
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error while saving channels: %s", err))
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
@@ -702,7 +704,9 @@ func TestDisconnect(t *testing.T) {
|
||||
})
|
||||
assert.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
chID = chs[0].ID
|
||||
chanRepo.Connect(context.Background(), email, []string{chID}, []string{thID})
|
||||
|
||||
err = chanRepo.Connect(context.Background(), email, []string{chID}, []string{thID})
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error while connecting to service: %s", err))
|
||||
|
||||
nonexistentThingID, err := idProvider.ID()
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
@@ -788,7 +792,9 @@ func TestHasThing(t *testing.T) {
|
||||
})
|
||||
assert.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
chID = chs[0].ID
|
||||
chanRepo.Connect(context.Background(), email, []string{chID}, []string{thID})
|
||||
|
||||
err = chanRepo.Connect(context.Background(), email, []string{chID}, []string{thID})
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error while connecting to service: %s", err))
|
||||
|
||||
nonexistentChanID, err := idProvider.ID()
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
@@ -866,7 +872,9 @@ func TestHasThingByID(t *testing.T) {
|
||||
})
|
||||
assert.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
chID = chs[0].ID
|
||||
chanRepo.Connect(context.Background(), email, []string{chID}, []string{thID})
|
||||
|
||||
err = chanRepo.Connect(context.Background(), email, []string{chID}, []string{thID})
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error while connecting to service: %s", err))
|
||||
|
||||
nonexistentChanID, err := idProvider.ID()
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
|
||||
@@ -48,7 +48,10 @@ func (tr thingRepository) Save(ctx context.Context, ths ...things.Thing) ([]thin
|
||||
}
|
||||
|
||||
if _, err := tx.NamedExecContext(ctx, q, dbth); err != nil {
|
||||
tx.Rollback()
|
||||
if rollbackErr := tx.Rollback(); rollbackErr != nil {
|
||||
err = errors.Wrap(err, rollbackErr)
|
||||
return []things.Thing{}, errors.Wrap(errors.ErrCreateEntity, err)
|
||||
}
|
||||
pgErr, ok := err.(*pgconn.PgError)
|
||||
if ok {
|
||||
switch pgErr.Code {
|
||||
@@ -158,9 +161,6 @@ func (tr thingRepository) RetrieveByID(ctx context.Context, owner, id string) (t
|
||||
}
|
||||
return things.Thing{}, errors.Wrap(errors.ErrViewEntity, err)
|
||||
}
|
||||
fmt.Println()
|
||||
fmt.Println(dbth)
|
||||
fmt.Println()
|
||||
return toThing(dbth)
|
||||
}
|
||||
|
||||
|
||||
@@ -395,10 +395,12 @@ func TestMultiThingRetrieval(t *testing.T) {
|
||||
subMetaStr := `{"field2":{"subfield12":{"subfield121":"value3"}}}`
|
||||
|
||||
metadata := things.Metadata{}
|
||||
json.Unmarshal([]byte(metaStr), &metadata)
|
||||
err = json.Unmarshal([]byte(metaStr), &metadata)
|
||||
assert.Nil(t, err, fmt.Sprintf("got expected error while unmarshalling %s\n", err))
|
||||
|
||||
subMeta := things.Metadata{}
|
||||
json.Unmarshal([]byte(subMetaStr), &subMeta)
|
||||
err = json.Unmarshal([]byte(subMetaStr), &subMeta)
|
||||
assert.Nil(t, err, fmt.Sprintf("got expected error while unmarshalling %s\n", err))
|
||||
|
||||
wrongMeta := things.Metadata{
|
||||
"field": "value1",
|
||||
|
||||
+17
-14
@@ -49,7 +49,10 @@ func (es eventStore) CreateThings(ctx context.Context, token string, ths ...thin
|
||||
MaxLenApprox: streamLen,
|
||||
Values: event.Encode(),
|
||||
}
|
||||
es.client.XAdd(ctx, record).Err()
|
||||
|
||||
if err = es.client.XAdd(ctx, record).Err(); err != nil {
|
||||
return sths, err
|
||||
}
|
||||
}
|
||||
|
||||
return sths, nil
|
||||
@@ -70,9 +73,8 @@ func (es eventStore) UpdateThing(ctx context.Context, token string, thing things
|
||||
MaxLenApprox: streamLen,
|
||||
Values: event.Encode(),
|
||||
}
|
||||
es.client.XAdd(ctx, record).Err()
|
||||
|
||||
return nil
|
||||
return es.client.XAdd(ctx, record).Err()
|
||||
}
|
||||
|
||||
// UpdateKey doesn't send event because key shouldn't be sent over stream.
|
||||
@@ -111,9 +113,8 @@ func (es eventStore) RemoveThing(ctx context.Context, token, id string) error {
|
||||
MaxLenApprox: streamLen,
|
||||
Values: event.Encode(),
|
||||
}
|
||||
es.client.XAdd(ctx, record).Err()
|
||||
|
||||
return nil
|
||||
return es.client.XAdd(ctx, record).Err()
|
||||
}
|
||||
|
||||
func (es eventStore) CreateChannels(ctx context.Context, token string, channels ...things.Channel) ([]things.Channel, error) {
|
||||
@@ -134,7 +135,9 @@ func (es eventStore) CreateChannels(ctx context.Context, token string, channels
|
||||
MaxLenApprox: streamLen,
|
||||
Values: event.Encode(),
|
||||
}
|
||||
es.client.XAdd(ctx, record).Err()
|
||||
if err = es.client.XAdd(ctx, record).Err(); err != nil {
|
||||
return schs, err
|
||||
}
|
||||
}
|
||||
|
||||
return schs, nil
|
||||
@@ -155,9 +158,7 @@ func (es eventStore) UpdateChannel(ctx context.Context, token string, channel th
|
||||
MaxLenApprox: streamLen,
|
||||
Values: event.Encode(),
|
||||
}
|
||||
es.client.XAdd(ctx, record).Err()
|
||||
|
||||
return nil
|
||||
return es.client.XAdd(ctx, record).Err()
|
||||
}
|
||||
|
||||
func (es eventStore) ViewChannel(ctx context.Context, token, id string) (things.Channel, error) {
|
||||
@@ -185,9 +186,7 @@ func (es eventStore) RemoveChannel(ctx context.Context, token, id string) error
|
||||
MaxLenApprox: streamLen,
|
||||
Values: event.Encode(),
|
||||
}
|
||||
es.client.XAdd(ctx, record).Err()
|
||||
|
||||
return nil
|
||||
return es.client.XAdd(ctx, record).Err()
|
||||
}
|
||||
|
||||
func (es eventStore) Connect(ctx context.Context, token string, chIDs, thIDs []string) error {
|
||||
@@ -206,7 +205,9 @@ func (es eventStore) Connect(ctx context.Context, token string, chIDs, thIDs []s
|
||||
MaxLenApprox: streamLen,
|
||||
Values: event.Encode(),
|
||||
}
|
||||
es.client.XAdd(ctx, record).Err()
|
||||
if err := es.client.XAdd(ctx, record).Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +230,9 @@ func (es eventStore) Disconnect(ctx context.Context, token string, chIDs, thIDs
|
||||
MaxLenApprox: streamLen,
|
||||
Values: event.Encode(),
|
||||
}
|
||||
es.client.XAdd(ctx, record).Err()
|
||||
if err := es.client.XAdd(ctx, record).Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,8 @@ func TestThingRemove(t *testing.T) {
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
||||
id := "123"
|
||||
id2 := "321"
|
||||
thingCache.Save(context.Background(), key, id)
|
||||
err = thingCache.Save(context.Background(), key, id)
|
||||
assert.Nil(t, err, fmt.Sprintf("got unexpected error while saving thingKey-thingID pair: %s", err))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
|
||||
+1
-1
@@ -244,7 +244,7 @@ func (ts *thingsService) claimOwnership(ctx context.Context, objectID string, ac
|
||||
for _, action := range actions {
|
||||
apr, err := ts.auth.AddPolicy(ctx, &mainflux.AddPolicyReq{Obj: objectID, Act: action, Sub: userID})
|
||||
if err != nil {
|
||||
errs = errors.Wrap(fmt.Errorf("cannot claim ownership on object '%s' by user '%s': %s", objectID, userID, err), errs)
|
||||
errs = errors.Wrap(fmt.Errorf("cannot claim ownership on object '%s' by user '%s': %w", objectID, userID, err), errs)
|
||||
}
|
||||
if !apr.GetAuthorized() {
|
||||
errs = errors.Wrap(fmt.Errorf("cannot claim ownership on object '%s' by user '%s': unauthorized", objectID, userID), errs)
|
||||
|
||||
@@ -14,33 +14,42 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
mflog "github.com/mainflux/mainflux/logger"
|
||||
"github.com/pelletier/go-toml"
|
||||
)
|
||||
|
||||
// Benchmark - main benchmarking function
|
||||
func Benchmark(cfg Config) {
|
||||
checkConnection(cfg.MQTT.Broker.URL, 1)
|
||||
logger, err := mflog.New(os.Stdout, mflog.Debug.String())
|
||||
if err != nil {
|
||||
log.Fatalf(err.Error())
|
||||
}
|
||||
|
||||
var err error
|
||||
subsResults := map[string](*[]float64){}
|
||||
var caByte []byte
|
||||
if cfg.MQTT.TLS.MTLS {
|
||||
caFile, err := os.Open(cfg.MQTT.TLS.CA)
|
||||
defer caFile.Close()
|
||||
|
||||
defer func() {
|
||||
if err = caFile.Close(); err != nil {
|
||||
logger.Warn(fmt.Sprintf("Could not close file: %s", err))
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
logger.Warn(err.Error())
|
||||
}
|
||||
caByte, _ = ioutil.ReadAll(caFile)
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(cfg.Mf.ConnFile)
|
||||
if err != nil {
|
||||
log.Fatalf("Error loading connections file: %s", err)
|
||||
logger.Fatal(fmt.Sprintf("Error loading connections file: %s", err))
|
||||
}
|
||||
|
||||
mf := mainflux{}
|
||||
if err := toml.Unmarshal(data, &mf); err != nil {
|
||||
log.Fatalf("Cannot load Mainflux connections config %s \nUse tools/provision to create file", cfg.Mf.ConnFile)
|
||||
logger.Fatal(fmt.Sprintf("Cannot load Mainflux connections config %s \nUse tools/provision to create file", cfg.Mf.ConnFile))
|
||||
}
|
||||
|
||||
resCh := make(chan *runResults)
|
||||
@@ -61,12 +70,12 @@ func Benchmark(cfg Config) {
|
||||
if cfg.MQTT.TLS.MTLS {
|
||||
cert, err = tls.X509KeyPair([]byte(mfThing.MTLSCert), []byte(mfThing.MTLSKey))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
c, err := makeClient(i, cfg, mfChan, mfThing, startStamp, caByte, cert)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to create message payload %s", err.Error())
|
||||
logger.Fatal(fmt.Sprintf("Unable to create message payload %s", err.Error()))
|
||||
}
|
||||
|
||||
go c.publish(resCh)
|
||||
@@ -110,7 +119,9 @@ func getBytePayload(size int, m message) (handler, error) {
|
||||
sz := size - n
|
||||
for {
|
||||
b = make([]byte, sz)
|
||||
rand.Read(b)
|
||||
if _, err = rand.Read(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m.Payload = b
|
||||
content, err := json.Marshal(&m)
|
||||
if err != nil {
|
||||
|
||||
@@ -147,7 +147,6 @@ func (c *Client) connect() error {
|
||||
cfg.Certificates = []tls.Certificate{c.ClientCert}
|
||||
}
|
||||
|
||||
cfg.BuildNameToCertificate()
|
||||
opts.SetTLSConfig(cfg)
|
||||
opts.SetProtocolVersion(4)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ func main() {
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "mqtt-bench",
|
||||
Short: "mqtt-bench is MQTT benchmark tool for Mainflux",
|
||||
Long: `Tool for exctensive load and benchmarking of MQTT brokers used withing Mainflux platform.
|
||||
Long: `Tool for exctensive load and benchmarking of MQTT brokers used within the Mainflux platform.
|
||||
Complete documentation is available at https://docs.mainflux.io`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if confFile != "" {
|
||||
@@ -62,7 +62,7 @@ Complete documentation is available at https://docs.mainflux.io`,
|
||||
rootCmd.PersistentFlags().IntVarP(&bconf.Test.Pubs, "pubs", "p", 10, "Number of publishers")
|
||||
|
||||
// Log params
|
||||
rootCmd.PersistentFlags().BoolVarP(&bconf.Log.Quiet, "quiet", "", false, "Supress messages")
|
||||
rootCmd.PersistentFlags().BoolVarP(&bconf.Log.Quiet, "quiet", "", false, "Suppress messages")
|
||||
|
||||
// Config file
|
||||
rootCmd.PersistentFlags().StringVarP(&confFile, "config", "c", "config.toml", "config file for mqtt-bench")
|
||||
|
||||
@@ -157,7 +157,9 @@ func printResults(results []*runResults, totals *totalResults, format string, qu
|
||||
log.Printf("Failed to prepare results for printing - %s\n", err.Error())
|
||||
}
|
||||
var out bytes.Buffer
|
||||
json.Indent(&out, data, "", "\t")
|
||||
if err = json.Indent(&out, data, "", "\t"); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(out.String())
|
||||
default:
|
||||
|
||||
@@ -392,7 +392,7 @@ func TestViewTwin(t *testing.T) {
|
||||
|
||||
var resData twinRes
|
||||
err = json.NewDecoder(res.Body).Decode(&resData)
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: got unexpected error while decoding json: %s", tc.desc, err))
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: got unexpected error while decoding response body: %s\n", tc.desc, err))
|
||||
assert.Equal(t, tc.res, resData, fmt.Sprintf("%s: expected body %v got %v", tc.desc, tc.res, resData))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
|
||||
const (
|
||||
statesCollection string = "states"
|
||||
twinid = "twinid"
|
||||
twinid string = "twinid"
|
||||
)
|
||||
|
||||
type stateRepository struct {
|
||||
|
||||
@@ -58,7 +58,8 @@ func TestStatesRetrieveAll(t *testing.T) {
|
||||
require.Nil(t, err, fmt.Sprintf("Creating new MongoDB client expected to succeed: %s.\n", err))
|
||||
|
||||
db := client.Database(testDB)
|
||||
db.Collection("states").DeleteMany(context.Background(), bson.D{})
|
||||
_, err = db.Collection("states").DeleteMany(context.Background(), bson.D{})
|
||||
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
|
||||
repo := mongodb.NewStateRepository(db)
|
||||
|
||||
@@ -73,7 +74,8 @@ func TestStatesRetrieveAll(t *testing.T) {
|
||||
Created: time.Now(),
|
||||
}
|
||||
|
||||
repo.Save(context.Background(), st)
|
||||
err = repo.Save(context.Background(), st)
|
||||
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
}
|
||||
|
||||
cases := map[string]struct {
|
||||
@@ -120,7 +122,8 @@ func TestStatesRetrieveLast(t *testing.T) {
|
||||
require.Nil(t, err, fmt.Sprintf("Creating new MongoDB client expected to succeed: %s.\n", err))
|
||||
|
||||
db := client.Database(testDB)
|
||||
db.Collection("states").DeleteMany(context.Background(), bson.D{})
|
||||
_, err = db.Collection("states").DeleteMany(context.Background(), bson.D{})
|
||||
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
|
||||
repo := mongodb.NewStateRepository(db)
|
||||
|
||||
@@ -135,7 +138,8 @@ func TestStatesRetrieveLast(t *testing.T) {
|
||||
Created: time.Now(),
|
||||
}
|
||||
|
||||
repo.Save(context.Background(), st)
|
||||
err = repo.Save(context.Background(), st)
|
||||
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
}
|
||||
|
||||
cases := map[string]struct {
|
||||
|
||||
@@ -249,7 +249,8 @@ func TestTwinsRetrieveAll(t *testing.T) {
|
||||
require.Nil(t, err, fmt.Sprintf("Creating new MongoDB client expected to succeed: %s.\n", err))
|
||||
|
||||
db := client.Database(testDB)
|
||||
db.Collection(collection).DeleteMany(context.Background(), bson.D{})
|
||||
_, err = db.Collection(collection).DeleteMany(context.Background(), bson.D{})
|
||||
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
|
||||
twinRepo := mongodb.NewTwinRepository(db)
|
||||
|
||||
@@ -269,7 +270,8 @@ func TestTwinsRetrieveAll(t *testing.T) {
|
||||
tw.Name = name
|
||||
}
|
||||
|
||||
twinRepo.Save(context.Background(), tw)
|
||||
_, err = twinRepo.Save(context.Background(), tw)
|
||||
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
}
|
||||
|
||||
cases := map[string]struct {
|
||||
|
||||
@@ -23,7 +23,7 @@ var (
|
||||
// ErrRedisTwinUpdate indicates error while saving Twin in redis cache
|
||||
ErrRedisTwinUpdate = errors.New("failed to update twin in redis cache")
|
||||
|
||||
// ErrRedisTwinIDs indicates error while geting Twin IDs from redis cache
|
||||
// ErrRedisTwinIDs indicates error while getting Twin IDs from redis cache
|
||||
ErrRedisTwinIDs = errors.New("failed to get twin id from redis cache")
|
||||
|
||||
// ErrRedisTwinRemove indicates error while removing Twin from redis cache
|
||||
|
||||
+5
-5
@@ -285,17 +285,17 @@ func (ts *twinsService) saveState(msg *messaging.Message, twinID string) error {
|
||||
|
||||
tw, err := ts.twins.RetrieveByID(ctx, twinID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Retrieving twin for %s failed: %s", msg.Publisher, err)
|
||||
return fmt.Errorf("retrieving twin for %s failed: %s", msg.Publisher, err)
|
||||
}
|
||||
|
||||
var recs []senml.Record
|
||||
if err := json.Unmarshal(msg.Payload, &recs); err != nil {
|
||||
return fmt.Errorf("Unmarshal payload for %s failed: %s", msg.Publisher, err)
|
||||
return fmt.Errorf("unmarshal payload for %s failed: %s", msg.Publisher, err)
|
||||
}
|
||||
|
||||
st, err := ts.states.RetrieveLast(ctx, tw.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Retrieve last state for %s failed: %s", msg.Publisher, err)
|
||||
return fmt.Errorf("retrieve last state for %s failed: %s", msg.Publisher, err)
|
||||
}
|
||||
|
||||
for _, rec := range recs {
|
||||
@@ -305,11 +305,11 @@ func (ts *twinsService) saveState(msg *messaging.Message, twinID string) error {
|
||||
return nil
|
||||
case update:
|
||||
if err := ts.states.Update(ctx, st); err != nil {
|
||||
return fmt.Errorf("Update state for %s failed: %s", msg.Publisher, err)
|
||||
return fmt.Errorf("update state for %s failed: %s", msg.Publisher, err)
|
||||
}
|
||||
case save:
|
||||
if err := ts.states.Save(ctx, st); err != nil {
|
||||
return fmt.Errorf("Save state for %s failed: %s", msg.Publisher, err)
|
||||
return fmt.Errorf("save state for %s failed: %s", msg.Publisher, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +154,8 @@ func TestListTwins(t *testing.T) {
|
||||
|
||||
n := uint64(10)
|
||||
for i := uint64(0); i < n; i++ {
|
||||
svc.AddTwin(context.Background(), token, twin, def)
|
||||
_, err := svc.AddTwin(context.Background(), token, twin, def)
|
||||
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
|
||||
@@ -273,7 +273,7 @@ func TestListUsers(t *testing.T) {
|
||||
err: errors.ErrAuthorization,
|
||||
},
|
||||
{
|
||||
desc: "list user with emtpy token",
|
||||
desc: "list user with empty token",
|
||||
token: "",
|
||||
size: 0,
|
||||
err: errors.ErrAuthentication,
|
||||
|
||||
+9
-9
@@ -54,9 +54,9 @@ import "github.com/golang-jwt/jwt/v4"
|
||||
|
||||
See [the project documentation](https://pkg.go.dev/github.com/golang-jwt/jwt/v4) for examples of usage:
|
||||
|
||||
* [Simple example of parsing and validating a token](https://pkg.go.dev/github.com/golang-jwt/jwt#example-Parse-Hmac)
|
||||
* [Simple example of building and signing a token](https://pkg.go.dev/github.com/golang-jwt/jwt#example-New-Hmac)
|
||||
* [Directory of Examples](https://pkg.go.dev/github.com/golang-jwt/jwt#pkg-examples)
|
||||
* [Simple example of parsing and validating a token](https://pkg.go.dev/github.com/golang-jwt/jwt/v4#example-Parse-Hmac)
|
||||
* [Simple example of building and signing a token](https://pkg.go.dev/github.com/golang-jwt/jwt/v4#example-New-Hmac)
|
||||
* [Directory of Examples](https://pkg.go.dev/github.com/golang-jwt/jwt/v4#pkg-examples)
|
||||
|
||||
## Extensions
|
||||
|
||||
@@ -96,7 +96,7 @@ A token is simply a JSON object that is signed by its author. this tells you exa
|
||||
* The author of the token was in the possession of the signing secret
|
||||
* The data has not been modified since it was signed
|
||||
|
||||
It's important to know that JWT does not provide encryption, which means anyone who has access to the token can read its contents. If you need to protect (encrypt) the data, there is a companion spec, `JWE`, that provides this functionality. JWE is currently outside the scope of this library.
|
||||
It's important to know that JWT does not provide encryption, which means anyone who has access to the token can read its contents. If you need to protect (encrypt) the data, there is a companion spec, `JWE`, that provides this functionality. The companion project https://github.com/golang-jwt/jwe aims at a (very) experimental implementation of the JWE standard.
|
||||
|
||||
### Choosing a Signing Method
|
||||
|
||||
@@ -110,10 +110,10 @@ Asymmetric signing methods, such as RSA, use different keys for signing and veri
|
||||
|
||||
Each signing method expects a different object type for its signing keys. See the package documentation for details. Here are the most common ones:
|
||||
|
||||
* The [HMAC signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodHMAC) (`HS256`,`HS384`,`HS512`) expect `[]byte` values for signing and validation
|
||||
* The [RSA signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodRSA) (`RS256`,`RS384`,`RS512`) expect `*rsa.PrivateKey` for signing and `*rsa.PublicKey` for validation
|
||||
* The [ECDSA signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodECDSA) (`ES256`,`ES384`,`ES512`) expect `*ecdsa.PrivateKey` for signing and `*ecdsa.PublicKey` for validation
|
||||
* The [EdDSA signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodEd25519) (`Ed25519`) expect `ed25519.PrivateKey` for signing and `ed25519.PublicKey` for validation
|
||||
* The [HMAC signing method](https://pkg.go.dev/github.com/golang-jwt/jwt/v4#SigningMethodHMAC) (`HS256`,`HS384`,`HS512`) expect `[]byte` values for signing and validation
|
||||
* The [RSA signing method](https://pkg.go.dev/github.com/golang-jwt/jwt/v4#SigningMethodRSA) (`RS256`,`RS384`,`RS512`) expect `*rsa.PrivateKey` for signing and `*rsa.PublicKey` for validation
|
||||
* The [ECDSA signing method](https://pkg.go.dev/github.com/golang-jwt/jwt/v4#SigningMethodECDSA) (`ES256`,`ES384`,`ES512`) expect `*ecdsa.PrivateKey` for signing and `*ecdsa.PublicKey` for validation
|
||||
* The [EdDSA signing method](https://pkg.go.dev/github.com/golang-jwt/jwt/v4#SigningMethodEd25519) (`Ed25519`) expect `ed25519.PrivateKey` for signing and `ed25519.PublicKey` for validation
|
||||
|
||||
### JWT and OAuth
|
||||
|
||||
@@ -131,7 +131,7 @@ This library uses descriptive error messages whenever possible. If you are not g
|
||||
|
||||
## More
|
||||
|
||||
Documentation can be found [on pkg.go.dev](https://pkg.go.dev/github.com/golang-jwt/jwt).
|
||||
Documentation can be found [on pkg.go.dev](https://pkg.go.dev/github.com/golang-jwt/jwt/v4).
|
||||
|
||||
The command line utility included in this project (cmd/jwt) provides a straightforward example of token creation and parsing as well as a useful tool for debugging your own integration. You'll also find several implementation examples in the documentation.
|
||||
|
||||
|
||||
+1
-5
@@ -265,9 +265,5 @@ func verifyIss(iss string, cmp string, required bool) bool {
|
||||
if iss == "" {
|
||||
return !required
|
||||
}
|
||||
if subtle.ConstantTimeCompare([]byte(iss), []byte(cmp)) != 0 {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
return subtle.ConstantTimeCompare([]byte(iss), []byte(cmp)) != 0
|
||||
}
|
||||
|
||||
+7
@@ -42,6 +42,13 @@ func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
|
||||
return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc)
|
||||
}
|
||||
|
||||
// ParseWithClaims parses, validates, and verifies like Parse, but supplies a default object implementing the Claims
|
||||
// interface. This provides default values which can be overridden and allows a caller to use their own type, rather
|
||||
// than the default MapClaims implementation of Claims.
|
||||
//
|
||||
// Note: If you provide a custom claim implementation that embeds one of the standard claims (such as RegisteredClaims),
|
||||
// make sure that a) you either embed a non-pointer version of the claims or b) if you are using a pointer, allocate the
|
||||
// proper memory for it before passing in the overall claims, otherwise you might run into a panic.
|
||||
func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
|
||||
token, parts, err := p.ParseUnverified(tokenString, claims)
|
||||
if err != nil {
|
||||
|
||||
+18
-2
@@ -14,6 +14,12 @@ import (
|
||||
// To use the non-recommended decoding, set this boolean to `true` prior to using this package.
|
||||
var DecodePaddingAllowed bool
|
||||
|
||||
// DecodeStrict will switch the codec used for decoding JWTs into strict mode.
|
||||
// In this mode, the decoder requires that trailing padding bits are zero, as described in RFC 4648 section 3.5.
|
||||
// Note that this is a global variable, and updating it will change the behavior on a package level, and is also NOT go-routine safe.
|
||||
// To use strict decoding, set this boolean to `true` prior to using this package.
|
||||
var DecodeStrict bool
|
||||
|
||||
// TimeFunc provides the current time when parsing token to validate "exp" claim (expiration time).
|
||||
// You can override it to use another time value. This is useful for testing or if your
|
||||
// server uses a different time zone than your tokens.
|
||||
@@ -99,6 +105,11 @@ func Parse(tokenString string, keyFunc Keyfunc, options ...ParserOption) (*Token
|
||||
return NewParser(options...).Parse(tokenString, keyFunc)
|
||||
}
|
||||
|
||||
// ParseWithClaims is a shortcut for NewParser().ParseWithClaims().
|
||||
//
|
||||
// Note: If you provide a custom claim implementation that embeds one of the standard claims (such as RegisteredClaims),
|
||||
// make sure that a) you either embed a non-pointer version of the claims or b) if you are using a pointer, allocate the
|
||||
// proper memory for it before passing in the overall claims, otherwise you might run into a panic.
|
||||
func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc, options ...ParserOption) (*Token, error) {
|
||||
return NewParser(options...).ParseWithClaims(tokenString, claims, keyFunc)
|
||||
}
|
||||
@@ -116,12 +127,17 @@ func EncodeSegment(seg []byte) string {
|
||||
// Deprecated: In a future release, we will demote this function to a non-exported function, since it
|
||||
// should only be used internally
|
||||
func DecodeSegment(seg string) ([]byte, error) {
|
||||
encoding := base64.RawURLEncoding
|
||||
|
||||
if DecodePaddingAllowed {
|
||||
if l := len(seg) % 4; l > 0 {
|
||||
seg += strings.Repeat("=", 4-l)
|
||||
}
|
||||
return base64.URLEncoding.DecodeString(seg)
|
||||
encoding = base64.URLEncoding
|
||||
}
|
||||
|
||||
return base64.RawURLEncoding.DecodeString(seg)
|
||||
if DecodeStrict {
|
||||
encoding = encoding.Strict()
|
||||
}
|
||||
return encoding.DecodeString(seg)
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -142,7 +142,7 @@ github.com/gofrs/uuid
|
||||
# github.com/gogo/protobuf v1.3.2
|
||||
## explicit; go 1.15
|
||||
github.com/gogo/protobuf/proto
|
||||
# github.com/golang-jwt/jwt/v4 v4.4.2
|
||||
# github.com/golang-jwt/jwt/v4 v4.5.0
|
||||
## explicit; go 1.16
|
||||
github.com/golang-jwt/jwt/v4
|
||||
# github.com/golang/protobuf v1.5.2
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
// Package ws contains the domain concept definitions needed to support
|
||||
// Mainflux ws adapter service functionality
|
||||
|
||||
package ws
|
||||
|
||||
import (
|
||||
|
||||
+2
-2
@@ -145,7 +145,7 @@ func process(svc ws.Service, req connReq, msgs <-chan []byte) {
|
||||
Payload: msg,
|
||||
Created: time.Now().UnixNano(),
|
||||
}
|
||||
svc.Publish(context.Background(), req.thingKey, &m)
|
||||
_ = svc.Publish(context.Background(), req.thingKey, &m)
|
||||
}
|
||||
if err := svc.Unsubscribe(context.Background(), req.thingKey, req.chanID, req.subtopic); err != nil {
|
||||
req.conn.Close()
|
||||
@@ -153,7 +153,7 @@ func process(svc ws.Service, req connReq, msgs <-chan []byte) {
|
||||
}
|
||||
|
||||
func encodeError(w http.ResponseWriter, err error) {
|
||||
statusCode := http.StatusUnauthorized
|
||||
var statusCode int
|
||||
|
||||
switch err {
|
||||
case ws.ErrEmptyID, ws.ErrEmptyTopic:
|
||||
|
||||
@@ -6,7 +6,6 @@ package mocks
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/mainflux/mainflux/pkg/messaging"
|
||||
@@ -37,7 +36,6 @@ func (pubsub *mockPubSub) Publish(ctx context.Context, s string, msg *messaging.
|
||||
if pubsub.conn != nil {
|
||||
data, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
fmt.Println("can't marshall")
|
||||
return ws.ErrFailedMessagePublish
|
||||
}
|
||||
return pubsub.conn.WriteMessage(websocket.BinaryMessage, data)
|
||||
|
||||
Reference in New Issue
Block a user