NOISSUE - Generate SDK Mocks (#127)

* fix(errors): Fix nil pointer error in NewSDKError

In the NewSDKError function, a check is added to handle the case where the input error is nil. Previously, if the error was nil, the function would panic. This fix ensures that the function returns nil instead of panicking when the input error is nil.

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>

* feat(sdk-mock): Add mock functions for SDK testing

This commit adds a set of mock functions for the software development kit (SDK) to facilitate testing. These functions simulate the behavior of the actual functions in the SDK and have defined input parameters and return values. The code also includes error handling logic and checks for different return types.

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>

* test: use sdk mocked interface

* feat(workflow): check for generated files

The commit modifies the check-proto GitHub workflow to check-generated files. It checks for changes in specific paths and verifies the protobuf files and generated mocks. The code also includes checking if the SDK mock is up to date, installing a tool, generating mocks, and displaying an error message if the mocks are different. The tool we use is: https://github.com/vektra/mockery.

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>

* feat(mocks): Add copyright notice to mocks.go

Added a copyright notice to the mocks.go file in the pkg/sdk/go directory for clarity and attribution.

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>

* feat(build): Add target for generating mocks

Added a new target to the Makefile for generating mocks using the mockery tool. The target checks if the mockery tool is installed and then runs the "go generate" command to generate mocks for the codebase..

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>

* Improve error messages in check-generated-files.yml

In this commit, I have made changes to the check-generated-files.yml file. Specifically, I have updated the error messages to provide more information about the issue. Instead of simply stating that the proto file and generated Go file are out of sync, the error message now includes a more detailed explanation and a suggestion for resolving the issue. Additionally, I have also added error messages for the generated mocks for the SDK. These error messages provide information about the sync issue and suggest running the necessary commands to resolve it. This commit aims to improve the clarity of error messages and help developers quickly identify and fix sync issues in the codebase.

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>

---------

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
This commit is contained in:
b1ackd0t
2023-12-15 11:25:05 +03:00
committed by GitHub
parent a8d3e7de42
commit aaf0756707
10 changed files with 3097 additions and 503 deletions
@@ -0,0 +1,97 @@
# Copyright (c) Abstract Machines
# SPDX-License-Identifier: Apache-2.0
name: Check the consistency of generated files
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
check-generated-files:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Go
uses: actions/setup-go@v4
with:
go-version: 1.21.x
cache-dependency-path: "go.sum"
- name: Check for changes in specific paths
uses: dorny/paths-filter@v2
id: changes
with:
base: main
filters: |
proto:
# - ".github/workflows/check-generated-files.yml"
- "auth.proto"
- "auth/*.pb.go"
- "pkg/messaging/message.proto"
- "pkg/messaging/*.pb.go"
sdk:
- ".github/workflows/check-generated-files.yml"
- "pkg/sdk/go/sdk.go"
- name: Set up protoc
if: steps.changes.outputs.proto == 'true'
run: |
PROTOC_VERSION=25.1
PROTOC_GEN_VERSION=v1.31.0
PROTOC_GRPC_VERSION=v1.3.0
# Download and install protoc
PROTOC_ZIP=protoc-$PROTOC_VERSION-linux-x86_64.zip
curl -0L -o $PROTOC_ZIP https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOC_VERSION/$PROTOC_ZIP
unzip -o $PROTOC_ZIP -d protoc3
sudo mv protoc3/bin/* /usr/local/bin/
sudo mv protoc3/include/* /usr/local/include/
rm -rf $PROTOC_ZIP protoc3
# Install protoc-gen-go and protoc-gen-go-grpc
go install google.golang.org/protobuf/cmd/protoc-gen-go@$PROTOC_GEN_VERSION
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@$PROTOC_GRPC_VERSION
# Add protoc to the PATH
export PATH=$PATH:/usr/local/bin/protoc
- name: Check Protobuf is up to Date
if: steps.changes.outputs.proto == 'true'
run: |
for p in $(find . -name "*.pb.go"); do
mv $p $p.tmp
done
make proto
for p in $(find . -name "*.pb.go"); do
if ! cmp -s $p $p.tmp; then
echo "Error: Proto file and generated Go file $p are out of sync!"
echo "Please run 'make proto' with protoc version $PROTOC_VERSION, protoc-gen-go version $PROTOC_GEN_VERSION and protoc-gen-go-grpc version $PROTOC_GRPC_VERSION and commit the changes."
exit 1
fi
done
- name: Check SDK is up to Date
if: steps.changes.outputs.sdk == 'true'
run: |
MOCKERY_VERSION=v2.38.0
go install github.com/vektra/mockery/v2@$MOCKERY_VERSION
mv ./pkg/sdk/go/mocks.go ./pkg/sdk/go/mocks.go.tmp
make mocks
if ! cmp -s ./pkg/sdk/go/mocks.go ./pkg/sdk/go/mocks.go.tmp; then
echo "Error: Generated mocks for SDK ./pkg/sdk/go/mocks.go are out of sync!"
echo "Please run 'make mocks' with mockery version $MOCKERY_VERSION and commit the changes."
exit 1
fi
-74
View File
@@ -1,74 +0,0 @@
# Copyright (c) Abstract Machines
# SPDX-License-Identifier: Apache-2.0
name: Check Proto File Consistency
on:
push:
branches:
- main
paths:
- ".github/workflows/check-proto.yml"
- "auth.proto"
- "auth/*.pb.go"
- "pkg/messaging/message.proto"
- "pkg/messaging/*.pb.go"
pull_request:
branches:
- main
paths:
- ".github/workflows/check-proto.yml"
- "auth.proto"
- "auth/*.pb.go"
- "pkg/messaging/message.proto"
- "pkg/messaging/*.pb.go"
jobs:
check-proto:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Go
uses: actions/setup-go@v4
with:
go-version: 1.21.x
cache-dependency-path: "go.sum"
- name: Set up protoc
run: |
PROTOC_VERSION=25.1
PROTOC_GEN_VERSION=v1.31.0
PROTOC_GRPC_VERSION=v1.3.0
# Download and install protoc
PROTOC_ZIP=protoc-$PROTOC_VERSION-linux-x86_64.zip
curl -0L -o $PROTOC_ZIP https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOC_VERSION/$PROTOC_ZIP
unzip -o $PROTOC_ZIP -d protoc3
sudo mv protoc3/bin/* /usr/local/bin/
sudo mv protoc3/include/* /usr/local/include/
rm -rf $PROTOC_ZIP protoc3
# Install protoc-gen-go and protoc-gen-go-grpc
go install google.golang.org/protobuf/cmd/protoc-gen-go@$PROTOC_GEN_VERSION
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@$PROTOC_GRPC_VERSION
# Add protoc to the PATH
export PATH=$PATH:/usr/local/bin/protoc
- name: Check Protobuf
run: |
for p in $(find . -name "*.pb.go"); do
mv $p $p.tmp
done
make proto
for p in $(find . -name "*.pb.go"); do
if ! cmp -s $p $p.tmp; then
echo "Proto file and generated Go file $p are out of sync!"
exit 1
fi
done
+5 -1
View File
@@ -122,8 +122,12 @@ install:
cp $$file $(GOBIN)/magistrala-`basename $$file`; \
done
mocks:
@which mockery > /dev/null || go install github.com/vektra/mockery/v2@latest
go generate ./...
DIRS = consumers readers postgres internal opcua
test:
test: mocks
mkdir -p coverage
@for dir in $(DIRS); do \
go test -v --race -count 1 -tags test -coverprofile=coverage/$$dir.out $$(go list ./... | grep $$dir | grep -v 'cmd'); \
+40 -109
View File
@@ -24,19 +24,10 @@ import (
bsapi "github.com/absmach/magistrala/bootstrap/api"
"github.com/absmach/magistrala/bootstrap/mocks"
"github.com/absmach/magistrala/internal/apiutil"
"github.com/absmach/magistrala/internal/groups"
chmocks "github.com/absmach/magistrala/internal/groups/mocks"
"github.com/absmach/magistrala/internal/testsutil"
mglog "github.com/absmach/magistrala/logger"
"github.com/absmach/magistrala/pkg/clients"
"github.com/absmach/magistrala/pkg/errors"
mggroups "github.com/absmach/magistrala/pkg/groups"
mgsdk "github.com/absmach/magistrala/pkg/sdk/go"
"github.com/absmach/magistrala/pkg/uuid"
"github.com/absmach/magistrala/things"
thapi "github.com/absmach/magistrala/things/api/http"
thmocks "github.com/absmach/magistrala/things/mocks"
"github.com/go-chi/chi/v5"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
@@ -184,32 +175,12 @@ func dec(in []byte) ([]byte, error) {
return in, nil
}
func newService(url string, auth magistrala.AuthServiceClient) bootstrap.Service {
thingsRepo := mocks.NewConfigsRepository()
config := mgsdk.Config{
ThingsURL: url,
}
sdk := mgsdk.NewSDK(config)
return bootstrap.New(auth, thingsRepo, sdk, encKey)
}
func newThingsService() (things.Service, mggroups.Service, *thmocks.Repository, *chmocks.Repository, *authmocks.Service) {
func newService() (bootstrap.Service, *authmocks.Service, *mgsdk.MockSDK) {
things := mocks.NewConfigsRepository()
auth := new(authmocks.Service)
thingCache := thmocks.NewCache()
idProvider := uuid.NewMock()
trepo := new(thmocks.Repository)
chrepo := new(chmocks.Repository)
sdk := &mgsdk.MockSDK{}
return things.NewService(auth, trepo, chrepo, thingCache, idProvider), groups.NewService(chrepo, idProvider, auth), trepo, chrepo, auth
}
func newThingsServer(tsvc things.Service, gsvc mggroups.Service) *httptest.Server {
logger := mglog.NewMock()
mux := chi.NewRouter()
thapi.MakeHandler(tsvc, gsvc, mux, logger, instanceID)
return httptest.NewServer(mux)
return bootstrap.New(auth, things, sdk, encKey), auth, sdk
}
func newBootstrapServer(svc bootstrap.Service) *httptest.Server {
@@ -227,9 +198,7 @@ func toJSON(data interface{}) string {
}
func TestAdd(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
bs := newBootstrapServer(svc)
data := toJSON(addReq)
@@ -333,9 +302,8 @@ func TestAdd(t *testing.T) {
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.auth}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: addThingID, Credentials: clients.Credentials{Secret: addThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: addThingID, Credentials: mgsdk.Credentials{Secret: addThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(mgsdk.Channel{}, nil)
req := testRequest{
client: bs.Client(),
method: http.MethodPost,
@@ -354,27 +322,22 @@ func TestAdd(t *testing.T) {
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
}
}
func TestView(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
bs := newBootstrapServer(svc)
c := newConfig()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: c.ThingID, Credentials: clients.Credentials{Secret: c.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: c.ThingID, Credentials: mgsdk.Credentials{Secret: c.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
saved, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
var channels []channel
for _, ch := range saved.Channels {
@@ -456,23 +419,19 @@ func TestView(t *testing.T) {
}
func TestUpdate(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
bs := newBootstrapServer(svc)
c := newConfig()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: c.ThingID, Credentials: clients.Credentials{Secret: c.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: c.ThingID, Credentials: mgsdk.Credentials{Secret: c.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
saved, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
data := toJSON(updateReq)
@@ -560,23 +519,19 @@ func TestUpdate(t *testing.T) {
}
func TestUpdateCert(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
bs := newBootstrapServer(svc)
c := newConfig()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: c.ThingID, Credentials: clients.Credentials{Secret: c.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: c.ThingID, Credentials: mgsdk.Credentials{Secret: c.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
saved, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
data := toJSON(updateReq)
@@ -664,23 +619,19 @@ func TestUpdateCert(t *testing.T) {
}
func TestUpdateConnections(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
bs := newBootstrapServer(svc)
c := newConfig()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: c.ThingID, Credentials: clients.Credentials{Secret: c.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: c.ThingID, Credentials: mgsdk.Credentials{Secret: c.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
saved, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
data := toJSON(updateReq)
@@ -765,11 +716,10 @@ func TestUpdateConnections(t *testing.T) {
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.auth}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: c.ThingID, Credentials: clients.Credentials{Secret: c.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, nil)
repoCall4 := auth.On("DeletePolicy", mock.Anything, mock.Anything).Return(&magistrala.DeletePolicyRes{Deleted: true}, nil)
repoCall5 := auth.On("AddPolicy", mock.Anything, mock.Anything).Return(&magistrala.AddPolicyRes{Authorized: true}, nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: c.ThingID, Credentials: mgsdk.Credentials{Secret: c.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(mgsdk.Channel{}, nil)
repoCall3 := auth.On("DeletePolicy", mock.Anything, mock.Anything).Return(&magistrala.DeletePolicyRes{Deleted: true}, nil)
repoCall4 := auth.On("AddPolicy", mock.Anything, mock.Anything).Return(&magistrala.AddPolicyRes{Authorized: true}, nil)
req := testRequest{
client: bs.Client(),
method: http.MethodPut,
@@ -786,7 +736,6 @@ func TestUpdateConnections(t *testing.T) {
repoCall2.Unset()
repoCall3.Unset()
repoCall4.Unset()
repoCall5.Unset()
}
}
@@ -796,9 +745,7 @@ func TestList(t *testing.T) {
var active, inactive []config
list := make([]config, configNum)
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
bs := newBootstrapServer(svc)
path := fmt.Sprintf("%s/%s", bs.URL, "things/configs")
@@ -811,15 +758,13 @@ func TestList(t *testing.T) {
c.ExternalKey = fmt.Sprintf("%s%s", addExternalKey, strconv.Itoa(i))
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: c.ThingID, Credentials: clients.Credentials{Secret: c.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: c.ThingID, Credentials: mgsdk.Credentials{Secret: c.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
saved, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
var channels []channel
for _, ch := range saved.Channels {
@@ -845,15 +790,13 @@ func TestList(t *testing.T) {
state = bootstrap.Inactive
}
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := auth.On("AddPolicies", mock.Anything, mock.Anything).Return(&magistrala.AddPoliciesRes{Authorized: true}, nil)
repoCall1 := sdk.On("Connect", mock.Anything, mock.Anything).Return(nil)
err := svc.ChangeState(context.Background(), validToken, list[i].ThingID, state)
assert.Nil(t, err, fmt.Sprintf("Changing state expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
list[i].State = state
if state == bootstrap.Inactive {
@@ -1062,23 +1005,19 @@ func TestList(t *testing.T) {
}
func TestRemove(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
bs := newBootstrapServer(svc)
c := newConfig()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: c.ThingID, Credentials: clients.Credentials{Secret: c.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: c.ThingID, Credentials: mgsdk.Credentials{Secret: c.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
saved, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
cases := []struct {
desc string
@@ -1134,23 +1073,19 @@ func TestRemove(t *testing.T) {
}
func TestBootstrap(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
bs := newBootstrapServer(svc)
c := newConfig()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: c.ThingID, Credentials: clients.Credentials{Secret: c.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: c.ThingID, Credentials: mgsdk.Credentials{Secret: c.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
saved, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
encExternKey, err := enc([]byte(c.ExternalKey))
assert.Nil(t, err, fmt.Sprintf("Encrypting config expected to succeed: %s.\n", err))
@@ -1272,23 +1207,19 @@ func TestBootstrap(t *testing.T) {
}
func TestChangeState(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
bs := newBootstrapServer(svc)
c := newConfig()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: c.ThingID, Credentials: clients.Credentials{Secret: c.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: c.ThingID, Credentials: mgsdk.Credentials{Secret: c.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
saved, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
inactive := fmt.Sprintf("{\"state\": %d}", bootstrap.Inactive)
active := fmt.Sprintf("{\"state\": %d}", bootstrap.Active)
@@ -1370,8 +1301,8 @@ func TestChangeState(t *testing.T) {
for _, tc := range cases {
repoCall = auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.auth}).Return(&magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, nil)
repoCall1 = auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 = auth.On("AddPolicies", mock.Anything, mock.Anything).Return(&magistrala.AddPoliciesRes{Authorized: true}, nil)
repoCall3 := auth.On("DeletePolicies", mock.Anything, mock.Anything).Return(&magistrala.DeletePoliciesRes{Deleted: true}, nil)
repoCall2 = sdk.On("Connect", mock.Anything, mock.Anything).Return(nil)
repoCall3 := sdk.On("DisconnectThing", mock.Anything, mock.Anything, mock.Anything).Return(nil)
req := testRequest{
client: bs.Client(),
method: http.MethodPut,
@@ -1414,8 +1345,8 @@ type configPage struct {
Configs []config `json:"configs"`
}
func toGroup(ch bootstrap.Channel) mggroups.Group {
return mggroups.Group{
func toGroup(ch bootstrap.Channel) mgsdk.Channel {
return mgsdk.Channel{
ID: ch.ID,
Name: ch.Name,
Metadata: ch.Metadata,
+44 -123
View File
@@ -7,7 +7,6 @@ import (
"context"
"encoding/json"
"fmt"
"net/http/httptest"
"strconv"
"strings"
"testing"
@@ -18,20 +17,10 @@ import (
"github.com/absmach/magistrala/bootstrap"
"github.com/absmach/magistrala/bootstrap/events/producer"
"github.com/absmach/magistrala/bootstrap/mocks"
"github.com/absmach/magistrala/internal/groups"
chmocks "github.com/absmach/magistrala/internal/groups/mocks"
"github.com/absmach/magistrala/internal/testsutil"
mglog "github.com/absmach/magistrala/logger"
"github.com/absmach/magistrala/pkg/clients"
"github.com/absmach/magistrala/pkg/errors"
svcerr "github.com/absmach/magistrala/pkg/errors/service"
mggroups "github.com/absmach/magistrala/pkg/groups"
mgsdk "github.com/absmach/magistrala/pkg/sdk/go"
"github.com/absmach/magistrala/pkg/uuid"
"github.com/absmach/magistrala/things"
thapi "github.com/absmach/magistrala/things/api/http"
thmocks "github.com/absmach/magistrala/things/mocks"
"github.com/go-chi/chi/v5"
"github.com/go-redis/redis/v8"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
@@ -86,41 +75,19 @@ var (
}
)
func newService(url string, auth magistrala.AuthServiceClient) bootstrap.Service {
configs := mocks.NewConfigsRepository()
config := mgsdk.Config{
ThingsURL: url,
}
sdk := mgsdk.NewSDK(config)
return bootstrap.New(auth, configs, sdk, encKey)
}
func newThingsService() (things.Service, mggroups.Service, *thmocks.Repository, *chmocks.Repository, *authmocks.Service) {
func newService() (bootstrap.Service, *authmocks.Service, *mgsdk.MockSDK) {
things := mocks.NewConfigsRepository()
auth := new(authmocks.Service)
thingCache := thmocks.NewCache()
idProvider := uuid.NewMock()
trepo := new(thmocks.Repository)
chrepo := new(chmocks.Repository)
sdk := &mgsdk.MockSDK{}
return things.NewService(auth, trepo, chrepo, thingCache, idProvider), groups.NewService(chrepo, idProvider, auth), trepo, chrepo, auth
}
func newThingsServer(tsvc things.Service, gsvc mggroups.Service) *httptest.Server {
logger := mglog.NewMock()
mux := chi.NewRouter()
thapi.MakeHandler(tsvc, gsvc, mux, logger, instanceID)
return httptest.NewServer(mux)
return bootstrap.New(auth, things, sdk, encKey), auth, sdk
}
func TestAdd(t *testing.T) {
err := redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
svc, err = producer.NewEventStoreMiddleware(context.Background(), svc, redisURL)
assert.Nil(t, err, fmt.Sprintf("got unexpected error on creating event store middleware: %s", err))
@@ -168,9 +135,8 @@ func TestAdd(t *testing.T) {
lastID := "0"
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, tc.err)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: tc.config.ThingID, Credentials: clients.Credentials{Secret: tc.config.ThingKey}}, tc.err)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(tc.config.Channels[0]), tc.err)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: tc.config.ThingID, Credentials: mgsdk.Credentials{Secret: tc.config.ThingKey}}, errors.NewSDKError(tc.err))
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toChannel(tc.config.Channels[0]), errors.NewSDKError(tc.err))
_, err := svc.Add(context.Background(), tc.token, tc.config)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
@@ -191,25 +157,20 @@ func TestAdd(t *testing.T) {
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
}
}
func TestView(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(config.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toChannel(config.Channels[0]), nil)
saved, err := svc.Add(context.Background(), validToken, config)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
repoCall = auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
svcConfig, svcErr := svc.View(context.Background(), validToken, saved.ThingID)
@@ -229,9 +190,7 @@ func TestUpdate(t *testing.T) {
err := redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
svc, err = producer.NewEventStoreMiddleware(context.Background(), svc, redisURL)
assert.Nil(t, err, fmt.Sprintf("go unexpected error on creating event store middleware: %s", err))
@@ -241,15 +200,13 @@ func TestUpdate(t *testing.T) {
ch.ID = testsutil.GenerateUUID(t)
c.Channels = append(c.Channels, ch)
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: c.ThingID, Credentials: clients.Credentials{Secret: c.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: c.ThingID, Credentials: mgsdk.Credentials{Secret: c.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toChannel(c.Channels[0]), nil)
saved, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
err = redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
@@ -328,22 +285,19 @@ func TestUpdateConnections(t *testing.T) {
err := redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
svc, err = producer.NewEventStoreMiddleware(context.Background(), svc, redisURL)
assert.Nil(t, err, fmt.Sprintf("go unexpected error on creating event store middleware: %s", err))
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(config.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toChannel(config.Channels[0]), nil)
saved, err := svc.Add(context.Background(), validToken, config)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
err = redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
@@ -381,11 +335,8 @@ func TestUpdateConnections(t *testing.T) {
lastID := "0"
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, nil)
repoCall4 := auth.On("DeletePolicy", mock.Anything, mock.Anything).Return(&magistrala.DeletePolicyRes{Deleted: true}, nil)
repoCall5 := auth.On("AddPolicy", mock.Anything, mock.Anything).Return(&magistrala.AddPolicyRes{Authorized: true}, nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(mgsdk.Channel{}, nil)
err := svc.UpdateConnections(context.Background(), tc.token, tc.id, tc.connections)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
@@ -405,9 +356,6 @@ func TestUpdateConnections(t *testing.T) {
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
repoCall4.Unset()
repoCall5.Unset()
}
}
@@ -415,21 +363,18 @@ func TestUpdateCert(t *testing.T) {
err := redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
svc, err = producer.NewEventStoreMiddleware(context.Background(), svc, redisURL)
assert.Nil(t, err, fmt.Sprintf("go unexpected error on creating event store middleware: %s", err))
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(config.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toChannel(config.Channels[0]), nil)
saved, err := svc.Add(context.Background(), validToken, config)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
err = redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
@@ -574,20 +519,17 @@ func TestUpdateCert(t *testing.T) {
}
func TestList(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(config.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toChannel(config.Channels[0]), nil)
_, err := svc.Add(context.Background(), validToken, config)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
offset := uint64(0)
limit := uint64(10)
repoCall = auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
@@ -606,24 +548,21 @@ func TestRemove(t *testing.T) {
err := redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
svc, err = producer.NewEventStoreMiddleware(context.Background(), svc, redisURL)
assert.Nil(t, err, fmt.Sprintf("go unexpected error on creating event store middleware: %s", err))
c := config
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(config.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toChannel(config.Channels[0]), nil)
saved, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
err = redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
@@ -681,24 +620,20 @@ func TestBootstrap(t *testing.T) {
err := redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
svc, err = producer.NewEventStoreMiddleware(context.Background(), svc, redisURL)
assert.Nil(t, err, fmt.Sprintf("go unexpected error on creating event store middleware: %s", err))
c := config
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(mgsdk.Channel{}, nil)
saved, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
err = redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
@@ -760,24 +695,20 @@ func TestChangeState(t *testing.T) {
err := redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
svc, err = producer.NewEventStoreMiddleware(context.Background(), svc, redisURL)
assert.Nil(t, err, fmt.Sprintf("go unexpected error on creating event store middleware: %s", err))
c := config
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toChannel(c.Channels[0]), nil)
saved, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
err = redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
@@ -817,8 +748,7 @@ func TestChangeState(t *testing.T) {
for _, tc := range cases {
repoCall = auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(&magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, nil)
repoCall1 = auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 = auth.On("AddPolicies", mock.Anything, mock.Anything).Return(&magistrala.AddPoliciesRes{Authorized: true}, nil)
repoCall3 := auth.On("DeletePolicy", mock.Anything, mock.Anything).Return(&magistrala.DeletePolicyRes{Deleted: true}, nil)
repoCall2 = sdk.On("Connect", mock.Anything, mock.Anything).Return(nil)
err := svc.ChangeState(context.Background(), tc.token, tc.id, tc.state)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
@@ -838,7 +768,6 @@ func TestChangeState(t *testing.T) {
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
}
}
@@ -846,9 +775,7 @@ func TestUpdateChannelHandler(t *testing.T) {
err := redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
tsvc, gsvc, _, _, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, _, _ := newService()
svc, err = producer.NewEventStoreMiddleware(context.Background(), svc, redisURL)
assert.Nil(t, err, fmt.Sprintf("go unexpected error on creating event store middleware: %s", err))
@@ -933,9 +860,7 @@ func TestRemoveChannelHandler(t *testing.T) {
err := redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
tsvc, gsvc, _, _, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, _, _ := newService()
svc, err = producer.NewEventStoreMiddleware(context.Background(), svc, redisURL)
assert.Nil(t, err, fmt.Sprintf("go unexpected error on creating event store middleware: %s", err))
@@ -1000,9 +925,7 @@ func TestRemoveConfigHandler(t *testing.T) {
err := redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
tsvc, gsvc, _, _, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, _, _ := newService()
svc, err = producer.NewEventStoreMiddleware(context.Background(), svc, redisURL)
assert.Nil(t, err, fmt.Sprintf("go unexpected error on creating event store middleware: %s", err))
@@ -1067,9 +990,7 @@ func TestDisconnectThingHandler(t *testing.T) {
err := redisClient.FlushAll(context.Background()).Err()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
tsvc, gsvc, _, _, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, _, _ := newService()
svc, err = producer.NewEventStoreMiddleware(context.Background(), svc, redisURL)
assert.Nil(t, err, fmt.Sprintf("go unexpected error on creating event store middleware: %s", err))
@@ -1192,8 +1113,8 @@ func test(t *testing.T, expected, actual map[string]interface{}, description str
}
}
func toGroup(ch bootstrap.Channel) mggroups.Group {
return mggroups.Group{
func toChannel(ch bootstrap.Channel) mgsdk.Channel {
return mgsdk.Channel{
ID: ch.ID,
Name: ch.Name,
Metadata: ch.Metadata,
+56 -151
View File
@@ -11,7 +11,6 @@ import (
"encoding/hex"
"fmt"
"io"
"net/http/httptest"
"sort"
"testing"
@@ -19,20 +18,10 @@ import (
authmocks "github.com/absmach/magistrala/auth/mocks"
"github.com/absmach/magistrala/bootstrap"
"github.com/absmach/magistrala/bootstrap/mocks"
"github.com/absmach/magistrala/internal/groups"
chmocks "github.com/absmach/magistrala/internal/groups/mocks"
"github.com/absmach/magistrala/internal/testsutil"
mglog "github.com/absmach/magistrala/logger"
"github.com/absmach/magistrala/pkg/clients"
"github.com/absmach/magistrala/pkg/errors"
svcerr "github.com/absmach/magistrala/pkg/errors/service"
mggroups "github.com/absmach/magistrala/pkg/groups"
mgsdk "github.com/absmach/magistrala/pkg/sdk/go"
"github.com/absmach/magistrala/pkg/uuid"
"github.com/absmach/magistrala/things"
thapi "github.com/absmach/magistrala/things/api/http"
thmocks "github.com/absmach/magistrala/things/mocks"
"github.com/go-chi/chi/v5"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
@@ -66,32 +55,12 @@ var (
}
)
func newService(url string, auth magistrala.AuthServiceClient) bootstrap.Service {
thingsRepo := mocks.NewConfigsRepository()
config := mgsdk.Config{
ThingsURL: url,
}
sdk := mgsdk.NewSDK(config)
return bootstrap.New(auth, thingsRepo, sdk, encKey)
}
func newThingsService() (things.Service, mggroups.Service, *thmocks.Repository, *chmocks.Repository, *authmocks.Service) {
func newService() (bootstrap.Service, *authmocks.Service, *mgsdk.MockSDK) {
things := mocks.NewConfigsRepository()
auth := new(authmocks.Service)
thingCache := thmocks.NewCache()
idProvider := uuid.NewMock()
trepo := new(thmocks.Repository)
chrepo := new(chmocks.Repository)
sdk := &mgsdk.MockSDK{}
return things.NewService(auth, trepo, chrepo, thingCache, idProvider), groups.NewService(chrepo, idProvider, auth), trepo, chrepo, auth
}
func newThingsServer(tsvc things.Service, gsvc mggroups.Service) *httptest.Server {
logger := mglog.NewMock()
mux := chi.NewRouter()
thapi.MakeHandler(tsvc, gsvc, mux, logger, instanceID)
return httptest.NewServer(mux)
return bootstrap.New(auth, things, sdk, encKey), auth, sdk
}
func enc(in []byte) ([]byte, error) {
@@ -110,9 +79,7 @@ func enc(in []byte) ([]byte, error) {
}
func TestAdd(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
neID := config
neID.ThingID = "non-existent"
@@ -155,9 +122,8 @@ func TestAdd(t *testing.T) {
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, tc.err)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: tc.config.ThingID, Credentials: clients.Credentials{Secret: tc.config.ThingKey}}, tc.err)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, tc.err)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: tc.config.ThingID, Credentials: mgsdk.Credentials{Secret: tc.config.ThingKey}}, errors.NewSDKError(tc.err))
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(mgsdk.Channel{}, errors.NewSDKError(tc.err))
_, err := svc.Add(context.Background(), tc.token, tc.config)
switch err {
case nil:
@@ -168,24 +134,19 @@ func TestAdd(t *testing.T) {
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
}
}
func TestView(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(mgsdk.Channel{}, nil)
saved, err := svc.Add(context.Background(), validToken, config)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
cases := []struct {
desc string
@@ -222,9 +183,7 @@ func TestView(t *testing.T) {
}
func TestUpdate(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
c := config
ch := channel
@@ -232,15 +191,13 @@ func TestUpdate(t *testing.T) {
c.Channels = append(c.Channels, ch)
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(mgsdk.Channel{}, nil)
saved, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
modifiedCreated := saved
modifiedCreated.Content = "new-config"
@@ -284,24 +241,20 @@ func TestUpdate(t *testing.T) {
}
func TestUpdateCert(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
c := config
ch := channel
ch.ID = "2"
c.Channels = append(c.Channels, ch)
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(mgsdk.Channel{}, nil)
saved, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
cases := []struct {
desc string
@@ -374,43 +327,35 @@ func TestUpdateCert(t *testing.T) {
}
func TestUpdateConnections(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
c := config
ch := channel
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
created, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
c.ExternalID = testsutil.GenerateUUID(t)
repoCall = auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 = auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 = trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 = chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
repoCall1 = sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 = sdk.On("Channel", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
active, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
repoCall = auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, nil)
repoCall1 = auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 = auth.On("AddPolicies", mock.Anything, mock.Anything).Return(&magistrala.AddPoliciesRes{Authorized: true}, nil)
repoCall1 = sdk.On("Connect", mock.Anything, mock.Anything).Return(nil)
err = svc.ChangeState(context.Background(), validToken, active.ThingID, bootstrap.Active)
assert.Nil(t, err, fmt.Sprintf("Changing state expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
nonExisting := config
nonExisting.ThingID = unknown
@@ -461,26 +406,18 @@ func TestUpdateConnections(t *testing.T) {
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, nil)
repoCall4 := auth.On("DeletePolicy", mock.Anything, mock.Anything).Return(&magistrala.DeletePolicyRes{Deleted: true}, nil)
repoCall5 := auth.On("AddPolicy", mock.Anything, mock.Anything).Return(&magistrala.AddPolicyRes{Authorized: true}, nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(mgsdk.Channel{}, nil)
err := svc.UpdateConnections(context.Background(), tc.token, tc.id, tc.connections)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
repoCall4.Unset()
repoCall5.Unset()
}
}
func TestList(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
numThings := 101
var saved []bootstrap.Config
for i := 0; i < numThings; i++ {
@@ -489,26 +426,22 @@ func TestList(t *testing.T) {
c.ExternalKey = testsutil.GenerateUUID(t)
c.Name = fmt.Sprintf("%s-%d", config.Name, i)
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: c.ThingID, Credentials: clients.Credentials{Secret: c.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: c.ThingID, Credentials: mgsdk.Credentials{Secret: c.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toGroup(c.Channels[0]), nil)
s, err := svc.Add(context.Background(), validToken, c)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
saved = append(saved, s)
}
// Set one Thing to the different state
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := auth.On("AddPolicies", mock.Anything, mock.Anything).Return(&magistrala.AddPoliciesRes{Authorized: true}, nil)
repoCall1 := sdk.On("Connect", mock.Anything, mock.Anything).Return(nil)
err := svc.ChangeState(context.Background(), validToken, saved[41].ThingID, bootstrap.Active)
assert.Nil(t, err, fmt.Sprintf("Changing config state expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
saved[41].State = bootstrap.Active
@@ -599,19 +532,15 @@ func TestList(t *testing.T) {
}
func TestRemove(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(mgsdk.Channel{}, nil)
saved, err := svc.Add(context.Background(), validToken, config)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
cases := []struct {
desc string
@@ -654,19 +583,15 @@ func TestRemove(t *testing.T) {
}
func TestBootstrap(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(mgsdk.Channel{}, nil)
saved, err := svc.Add(context.Background(), validToken, config)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
e, err := enc([]byte(saved.ExternalKey))
assert.Nil(t, err, fmt.Sprintf("Encrypting external key expected to succeed: %s.\n", err))
@@ -721,19 +646,15 @@ func TestBootstrap(t *testing.T) {
}
func TestChangeState(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(toGroup(config.Channels[0]), nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(toGroup(config.Channels[0]), nil)
saved, err := svc.Add(context.Background(), validToken, config)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
cases := []struct {
desc string
@@ -780,33 +701,27 @@ func TestChangeState(t *testing.T) {
}
for _, tc := range cases {
repoCall = auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(&magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, nil)
repoCall1 = auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 = auth.On("AddPolicies", mock.Anything, mock.Anything).Return(&magistrala.AddPoliciesRes{Authorized: true}, nil)
repoCall3 := auth.On("DeletePolicies", mock.Anything, mock.Anything).Return(&magistrala.DeletePoliciesRes{Deleted: true}, nil)
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(&magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, nil)
repoCall1 := sdk.On("Connect", mock.Anything, mock.Anything).Return(nil)
repoCall2 := sdk.On("DisconnectThing", mock.Anything, mock.Anything, mock.Anything).Return(nil)
err := svc.ChangeState(context.Background(), tc.token, tc.id, tc.state)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
}
}
func TestUpdateChannelHandler(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(mgsdk.Channel{}, nil)
_, err := svc.Add(context.Background(), validToken, config)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
ch := bootstrap.Channel{
ID: channel.ID,
Name: "new name",
@@ -837,19 +752,16 @@ func TestUpdateChannelHandler(t *testing.T) {
}
func TestRemoveChannelHandler(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(mgsdk.Channel{}, nil)
_, err := svc.Add(context.Background(), validToken, config)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
cases := []struct {
desc string
id string
@@ -874,19 +786,15 @@ func TestRemoveChannelHandler(t *testing.T) {
}
func TestRemoveCoinfigHandler(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(mgsdk.Channel{}, nil)
saved, err := svc.Add(context.Background(), validToken, config)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
cases := []struct {
desc string
@@ -912,19 +820,16 @@ func TestRemoveCoinfigHandler(t *testing.T) {
}
func TestDisconnectThingsHandler(t *testing.T) {
tsvc, gsvc, trepo, chrepo, auth := newThingsService()
ts := newThingsServer(tsvc, gsvc)
svc := newService(ts.URL, auth)
svc, auth, sdk := newService()
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: config.ThingID, Credentials: clients.Credentials{Secret: config.ThingKey}}, nil)
repoCall3 := chrepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, nil)
repoCall1 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: config.ThingID, Credentials: mgsdk.Credentials{Secret: config.ThingKey}}, nil)
repoCall2 := sdk.On("Channel", mock.Anything, mock.Anything).Return(mgsdk.Channel{}, nil)
saved, err := svc.Add(context.Background(), validToken, config)
assert.Nil(t, err, fmt.Sprintf("Saving config expected to succeed: %s.\n", err))
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
cases := []struct {
desc string
thingID string
@@ -951,8 +856,8 @@ func TestDisconnectThingsHandler(t *testing.T) {
}
}
func toGroup(ch bootstrap.Channel) mggroups.Group {
return mggroups.Group{
func toGroup(ch bootstrap.Channel) mgsdk.Channel {
return mgsdk.Channel{
ID: ch.ID,
Name: ch.Name,
Metadata: ch.Metadata,
+14 -45
View File
@@ -6,7 +6,6 @@ package certs_test
import (
"context"
"fmt"
"net/http/httptest"
"strings"
"testing"
"time"
@@ -15,17 +14,9 @@ import (
authmocks "github.com/absmach/magistrala/auth/mocks"
"github.com/absmach/magistrala/certs"
"github.com/absmach/magistrala/certs/mocks"
chmocks "github.com/absmach/magistrala/internal/groups/mocks"
mglog "github.com/absmach/magistrala/logger"
"github.com/absmach/magistrala/pkg/clients"
"github.com/absmach/magistrala/pkg/errors"
svcerr "github.com/absmach/magistrala/pkg/errors/service"
mgsdk "github.com/absmach/magistrala/pkg/sdk/go"
"github.com/absmach/magistrala/pkg/uuid"
"github.com/absmach/magistrala/things"
httpapi "github.com/absmach/magistrala/things/api/http"
thmocks "github.com/absmach/magistrala/things/mocks"
"github.com/go-chi/chi/v5"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
@@ -50,23 +41,10 @@ const (
instanceID = "5de9b29a-feb9-11ed-be56-0242ac120002"
)
func newThingsServer(svc things.Service) *httptest.Server {
logger := mglog.NewMock()
mux := chi.NewMux()
httpapi.MakeHandler(svc, nil, mux, logger, instanceID)
return httptest.NewServer(mux)
}
func newService(t *testing.T) (certs.Service, *authmocks.Service, *thmocks.Repository) {
func newService(t *testing.T) (certs.Service, *authmocks.Service, *mgsdk.MockSDK) {
auth := new(authmocks.Service)
tsvc, trepo := newThingsService(auth)
server := newThingsServer(tsvc)
config := mgsdk.Config{
ThingsURL: server.URL,
}
sdk := mgsdk.NewSDK(config)
sdk := &mgsdk.MockSDK{}
repo := mocks.NewCertsRepository()
tlsCert, caCert, err := certs.LoadCertificates(caPath, caKeyPath)
@@ -77,20 +55,11 @@ func newService(t *testing.T) (certs.Service, *authmocks.Service, *thmocks.Repos
pki := mocks.NewPkiAgent(tlsCert, caCert, cfgSignHoursValid, authTimeout)
return certs.New(auth, repo, sdk, pki), auth, trepo
}
func newThingsService(auth *authmocks.Service) (things.Service, *thmocks.Repository) {
thingCache := thmocks.NewCache()
idProvider := uuid.NewMock()
cRepo := new(thmocks.Repository)
gRepo := new(chmocks.Repository)
return things.NewService(auth, cRepo, gRepo, thingCache, idProvider), cRepo
return certs.New(auth, repo, sdk, pki), auth, sdk
}
func TestIssueCert(t *testing.T) {
svc, auth, trepo := newService(t)
svc, auth, sdk := newService(t)
cases := []struct {
token string
@@ -126,7 +95,7 @@ func TestIssueCert(t *testing.T) {
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, tc.err)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: tc.thingID, Credentials: clients.Credentials{Secret: thingKey}}, tc.err)
repoCall2 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: tc.thingID, Credentials: mgsdk.Credentials{Secret: thingKey}}, errors.NewSDKError(tc.err))
c, err := svc.IssueCert(context.Background(), tc.token, tc.thingID, tc.ttl)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
cert, _ := certs.ReadCert([]byte(c.ClientCert))
@@ -140,11 +109,11 @@ func TestIssueCert(t *testing.T) {
}
func TestRevokeCert(t *testing.T) {
svc, auth, trepo := newService(t)
svc, auth, sdk := newService(t)
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: token}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: thingID, Credentials: clients.Credentials{Secret: thingKey}}, nil)
repoCall2 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: thingID, Credentials: mgsdk.Credentials{Secret: thingKey}}, nil)
_, err := svc.IssueCert(context.Background(), token, thingID, ttl)
require.Nil(t, err, fmt.Sprintf("unexpected service creation error: %s\n", err))
repoCall.Unset()
@@ -180,7 +149,7 @@ func TestRevokeCert(t *testing.T) {
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, tc.err)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: tc.thingID, Credentials: clients.Credentials{Secret: thingKey}}, tc.err)
repoCall2 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: tc.thingID, Credentials: mgsdk.Credentials{Secret: thingKey}}, errors.NewSDKError(tc.err))
_, err := svc.RevokeCert(context.Background(), tc.token, tc.thingID)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
repoCall.Unset()
@@ -190,12 +159,12 @@ func TestRevokeCert(t *testing.T) {
}
func TestListCerts(t *testing.T) {
svc, auth, trepo := newService(t)
svc, auth, sdk := newService(t)
for i := 0; i < certNum; i++ {
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: token}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: thingID, Credentials: clients.Credentials{Secret: thingKey}}, nil)
repoCall2 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: thingID, Credentials: mgsdk.Credentials{Secret: thingKey}}, nil)
_, err := svc.IssueCert(context.Background(), token, thingID, ttl)
require.Nil(t, err, fmt.Sprintf("unexpected cert creation error: %s\n", err))
repoCall.Unset()
@@ -261,13 +230,13 @@ func TestListCerts(t *testing.T) {
}
func TestListSerials(t *testing.T) {
svc, auth, trepo := newService(t)
svc, auth, sdk := newService(t)
var issuedCerts []certs.Cert
for i := 0; i < certNum; i++ {
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: token}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: thingID, Credentials: clients.Credentials{Secret: thingKey}}, nil)
repoCall2 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: thingID, Credentials: mgsdk.Credentials{Secret: thingKey}}, nil)
cert, err := svc.IssueCert(context.Background(), token, thingID, ttl)
assert.Nil(t, err, fmt.Sprintf("unexpected cert creation error: %s\n", err))
repoCall.Unset()
@@ -340,11 +309,11 @@ func TestListSerials(t *testing.T) {
}
func TestViewCert(t *testing.T) {
svc, auth, trepo := newService(t)
svc, auth, sdk := newService(t)
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: token}).Return(&magistrala.IdentityRes{Id: validID}, nil)
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
repoCall2 := trepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(clients.Client{ID: thingID, Credentials: clients.Credentials{Secret: thingKey}}, nil)
repoCall2 := sdk.On("Thing", mock.Anything, mock.Anything).Return(mgsdk.Thing{ID: thingID, Credentials: mgsdk.Credentials{Secret: thingKey}}, nil)
ic, err := svc.IssueCert(context.Background(), token, thingID, ttl)
require.Nil(t, err, fmt.Sprintf("unexpected cert creation error: %s\n", err))
repoCall.Unset()
+4
View File
@@ -47,6 +47,10 @@ func (ce *sdkError) StatusCode() int {
// NewSDKError returns an SDK Error that formats as the given text.
func NewSDKError(err error) SDKError {
if err == nil {
return nil
}
if e, ok := err.(Error); ok {
return &sdkError{
statusCode: 0,
+2835
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -109,6 +109,8 @@ type Credentials struct {
}
// SDK contains Magistrala API.
//
//go:generate mockery --name SDK --inpackage --filename mocks.go --quiet --note "Copyright (c) Abstract Machines"
type SDK interface {
// CreateUser registers magistrala user.
//