Repository: clouditor/clouditor
Pull request #226 (2021-05-30 17:38:12)

Added codecov action

codecov[bot]: # [Codecov](https://codecov.io/gh/clouditor/clouditor/pull/226?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) Report
> :exclamation: No coverage uploaded for pull request base (`main@de18612`). [Click here to learn what that means](https://docs.codecov.io/docs/error-reference?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#section-missing-base-commit).
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/clouditor/clouditor/pull/226/graphs/tree.svg?width=650&height=150&src=pr&token=VC87ODO814&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)](https://codecov.io/gh/clouditor/clouditor/pull/226?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)

```diff
@@          Coverage Diff           @@
##             main    #226   +/-   ##
======================================
  Coverage        ?   6.60%           
======================================
  Files           ?      31           
  Lines           ?    2649           
  Branches        ?       0           
======================================
  Hits            ?     175           
  Misses          ?    2465           
  Partials        ?       9           
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `6.60% <0.00%> (?)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#carryforward-flags-in-the-pull-request-comment) to find out more.


------

[Continue to review full report at Codecov](https://codecov.io/gh/clouditor/clouditor/pull/226?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/clouditor/clouditor/pull/226?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor). Last update [de18612...9d63cb5](https://codecov.io/gh/clouditor/clouditor/pull/226?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor).

codecov[bot]: # [Codecov](https://codecov.io/gh/clouditor/clouditor/pull/226?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) Report
> :exclamation: No coverage uploaded for pull request base (`main@de18612`). [Click here to learn what that means](https://docs.codecov.io/docs/error-reference?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#section-missing-base-commit).
> The diff coverage is `n/a`.

> :exclamation: Current head 5a3323c differs from pull request most recent head e37575d. Consider uploading reports for the commit e37575d to get more accurate results
[![Impacted file tree graph](https://codecov.io/gh/clouditor/clouditor/pull/226/graphs/tree.svg?width=650&height=150&src=pr&token=VC87ODO814&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)](https://codecov.io/gh/clouditor/clouditor/pull/226?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)

```diff
@@           Coverage Diff           @@
##             main     #226   +/-   ##
=======================================
  Coverage        ?   91.48%           
=======================================
  Files           ?        1           
  Lines           ?       47           
  Branches        ?        0           
=======================================
  Hits            ?       43           
  Misses          ?        4           
  Partials        ?        0           
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `91.48% <0.00%> (?)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#carryforward-flags-in-the-pull-request-comment) to find out more.


------

[Continue to review full report at Codecov](https://codecov.io/gh/clouditor/clouditor/pull/226?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/clouditor/clouditor/pull/226?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor). Last update [de18612...e37575d](https://codecov.io/gh/clouditor/clouditor/pull/226?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor).


Patch:
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 2b45c7ee..82efca21 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -65,18 +65,19 @@ jobs:
           go generate ./...
       - name: Build
         run: |
-          go test -v ./...
-          go build ./...
-      - name: "Upload Artifact"
-        uses: actions/upload-artifact@v2
+          go test -v -coverprofile=coverage.cov -coverpkg ./... -covermode=atomic ./...
+          mkdir -p build
+          go build -o build ./...
+      - uses: codecov/codecov-action@v1
         with:
-          name: engine
-          path: engine
+          files: coverage.cov
+          flags: unittests
+          verbose: true
       - name: "Upload Artifact"
         uses: actions/upload-artifact@v2
         with:
-          name: cl
-          path: cl
+          name: build
+          path: build
   lint:
     runs-on: ubuntu-latest
     steps:
@@ -85,7 +86,7 @@ jobs:
       - name: Lint
         uses: golangci/golangci-lint-action@v2
         with:
-          args: --timeout=10m        
+          args: --timeout=10m
       - name: Check for Missing Copyright Header
         run: |
           go install github.com/google/addlicense
diff --git a/README.md b/README.md
index 1ded2410..066551dc 100644
--- a/README.md
+++ b/README.md
@@ -4,13 +4,13 @@
 ![build](https://github.com/clouditor/clouditor/workflows/build/badge.svg) 
 [![](https://godoc.org/clouditor.io/clouditor?status.svg)](https://pkg.go.dev/clouditor.io/clouditor)
 [![Go Report Card](https://goreportcard.com/badge/clouditor.io/clouditor)](https://goreportcard.com/report/clouditor.io/clouditor)
+[![codecov](https://codecov.io/gh/clouditor/clouditor/branch/main/graph/badge.svg)](https://codecov.io/gh/clouditor/clouditor)
 [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=clouditor_clouditor&metric=alert_status)](https://sonarcloud.io/dashboard?id=clouditor_clouditor) 
 [![Docker Pulls](https://img.shields.io/docker/pulls/clouditor/clouditor.svg)](https://hub.docker.com/r/clouditor/clouditor)
 [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=clouditor_clouditor&metric=coverage)](https://sonarcloud.io/dashboard?id=clouditor_clouditor) 
 [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=clouditor_clouditor&metric=bugs)](https://sonarcloud.io/dashboard?id=clouditor_clouditor) 
 [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=clouditor_clouditor&metric=vulnerabilities)](https://sonarcloud.io/dashboard?id=clouditor_clouditor)
 
-
 ## Introduction
 
 Clouditor is a tool which supports continuous cloud assurance. Its main goal is to continuously evaluate if a cloud-based application (built using, e.g., Amazon Web Services (AWS) or Microsoft Azure) is configured in a secure way and thus complies with security requirements defined by, e.g., Cloud Computing Compliance Controls Catalogue (C5) issued by the German Office for Information Security (BSI) or the Cloud Control Matrix (CCM) published by the Cloud Security Alliance (CSA).
diff --git a/cmd/engine/engine.go b/cmd/engine/engine.go
index 724372c7..5bfa5257 100644
--- a/cmd/engine/engine.go
+++ b/cmd/engine/engine.go
@@ -163,7 +163,7 @@ func doCmd(cmd *cobra.Command, args []string) (err error) {
 		TokenSecret: viper.GetString(APISecretFlag),
 	}
 
-	discoveryService = &service_discovery.Service{}
+	discoveryService = service_discovery.NewService()
 	orchestratorService = &service_orchestrator.Service{}
 
 	createDefaultUser()
diff --git a/go.mod b/go.mod
index 51908a80..12de48b7 100644
--- a/go.mod
+++ b/go.mod
@@ -17,6 +17,7 @@ require (
 	github.com/sirupsen/logrus v1.8.1
 	github.com/spf13/cobra v1.1.3
 	github.com/spf13/viper v1.7.1
+	github.com/stretchr/testify v1.7.0 // indirect
 	golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
 	google.golang.org/genproto v0.0.0-20210524171403-669157292da3
 	google.golang.org/grpc v1.38.0
diff --git a/service/discovery/discovery.go b/service/discovery/discovery.go
index 50403c5b..ca704355 100644
--- a/service/discovery/discovery.go
+++ b/service/discovery/discovery.go
@@ -43,16 +43,24 @@ var log *logrus.Entry
 
 //go:generate protoc -I ../../proto -I ../../third_party discovery.proto --go_out=../.. --go-grpc_out=../.. --openapi_out=../../openapi/discovery
 
-// Service is an implementation of the Clouditor Discovery service
+// Service is an implementation of the Clouditor Discovery service.
+// It should not be used directly, but rather the NewService constructor
+// should be used.
 type Service struct {
 	discovery.UnimplementedDiscoveryServer
+
+	resources map[string]voc.IsResource
 }
 
 func init() {
 	log = logrus.WithField("component", "discovery")
 }
 
-var resources map[string]voc.IsResource = make(map[string]voc.IsResource)
+func NewService() *Service {
+	return &Service{
+		resources: make(map[string]voc.IsResource),
+	}
+}
 
 // Start starts discovery
 func (s Service) Start(ctx context.Context, request *discovery.StartDiscoveryRequest) (response *discovery.StartDiscoveryResponse, err error) {
@@ -62,19 +70,23 @@ func (s Service) Start(ctx context.Context, request *discovery.StartDiscoveryReq
 
 	var discoverer discovery.Discoverer = azure.NewAzureStorageDiscovery()
 
+	s.StartDiscovery(discoverer)
+
+	return response, nil
+}
+
+func (s Service) StartDiscovery(discoverer discovery.Discoverer) {
 	list, _ := discoverer.List()
 
 	for _, v := range list {
-		resources[string(v.GetID())] = v
+		s.resources[string(v.GetID())] = v
 	}
-
-	return response, nil
 }
 
 func (s Service) Query(ctx context.Context, request *emptypb.Empty) (response *discovery.QueryResponse, err error) {
 	var r []*structpb.Value
 
-	for _, v := range resources {
+	for _, v := range s.resources {
 		var s structpb.Value
 
 		// this is probably not the fastest approach, but this
diff --git a/service/orchestrator/orchestrator.go b/service/orchestrator/orchestrator.go
index bc717dce..6ef7760c 100644
--- a/service/orchestrator/orchestrator.go
+++ b/service/orchestrator/orchestrator.go
@@ -25,7 +25,7 @@
  * This file is part of Clouditor Community Edition.
  */
 
-package discovery
+package orchestrator
 
 import (
 	"context"


Test patch:
diff --git a/service/discovery/discovery_test.go b/service/discovery/discovery_test.go
new file mode 100644
index 00000000..bb1a7596
--- /dev/null
+++ b/service/discovery/discovery_test.go
@@ -0,0 +1,60 @@
+package discovery_test
+
+import (
+	"context"
+	"testing"
+
+	"clouditor.io/clouditor/api/discovery"
+	service_discovery "clouditor.io/clouditor/service/discovery"
+	"clouditor.io/clouditor/voc"
+	"github.com/stretchr/testify/assert"
+	"google.golang.org/protobuf/types/known/emptypb"
+)
+
+var service *service_discovery.Service
+
+type mockDiscoverer struct {
+}
+
+func (m mockDiscoverer) List() ([]voc.IsResource, error) {
+	return []voc.IsResource{
+		&voc.ObjectStorageResource{
+			StorageResource: voc.StorageResource{
+				Resource: voc.Resource{
+					ID:   "some-id",
+					Name: "some-name",
+				},
+			},
+		},
+	}, nil
+}
+
+func TestQuery(t *testing.T) {
+	var (
+		discoverer discovery.Discoverer
+		response   *discovery.QueryResponse
+		err        error
+	)
+
+	service = service_discovery.NewService()
+
+	// use our mock discoverer
+	discoverer = mockDiscoverer{}
+
+	// discover some resources
+	service.StartDiscovery(discoverer)
+
+	// query them
+	response, err = service.Query(context.Background(), &emptypb.Empty{})
+
+	assert.Nil(t, err)
+	assert.NotNil(t, response)
+
+	assert.NotEmpty(t, response.Result.Values)
+
+	m := response.Result.Values[0].GetStructValue().AsMap()
+
+	assert.NotNil(t, m)
+	assert.Equal(t, "some-id", m["id"])
+	assert.Equal(t, "some-name", m["name"])
+}
diff --git a/service/orchestrator/orchestrator_test.go b/service/orchestrator/orchestrator_test.go
new file mode 100644
index 00000000..331ed9a5
--- /dev/null
+++ b/service/orchestrator/orchestrator_test.go
@@ -0,0 +1,43 @@
+package orchestrator_test
+
+import (
+	"context"
+	"testing"
+
+	"clouditor.io/clouditor/api/assessment"
+	"clouditor.io/clouditor/api/orchestrator"
+	service_orchestrator "clouditor.io/clouditor/service/orchestrator"
+	"github.com/stretchr/testify/assert"
+)
+
+var service service_orchestrator.Service
+
+func TestListMetrics(t *testing.T) {
+	var (
+		response *orchestrator.ListMetricsResponse
+		err      error
+	)
+
+	response, err = service.ListMetrics(context.TODO(), &orchestrator.ListMetricsRequest{})
+
+	assert.Nil(t, err)
+	assert.NotEmpty(t, response.Metrics)
+}
+
+func TestGetMetric(t *testing.T) {
+	var (
+		request *orchestrator.GetMetricsRequest
+		metric  *assessment.Metric
+		err     error
+	)
+
+	request = &orchestrator.GetMetricsRequest{
+		MetricId: 1,
+	}
+
+	metric, err = service.GetMetric(context.TODO(), request)
+
+	assert.Nil(t, err)
+	assert.NotNil(t, metric)
+	assert.Equal(t, request.MetricId, metric.Id)
+}