Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(test): add end to end tests skeleton and some basic tests #539

Merged
merged 44 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
97b4457
E2E tests skeleton
adamtagscherer May 11, 2023
2c0120b
Fix go.mod
adamtagscherer May 11, 2023
67037c7
Fix go.mod
adamtagscherer May 11, 2023
1f5654c
fix: importing github.com/spdx/tools-golang
chrisgacsal May 11, 2023
5aa9e94
Fix go.mod
adamtagscherer May 11, 2023
4e01dd2
Fix go.mod
adamtagscherer May 11, 2023
19d4390
implement post scan config client method
adamtagscherer May 12, 2023
3427fdd
feat: add logging to E2E tests
adamtagscherer May 16, 2023
79634a3
feat: add reuse existing local docker vms for tests
adamtagscherer May 16, 2023
6e252d1
feat: abort scan test case flow
adamtagscherer May 17, 2023
347e221
feat: add additional options for compose up and down
adamtagscherer May 17, 2023
9c656df
fix: remove deprecated scan scope
paralta Jul 28, 2023
da274e1
feat(e2e): add docker compose file, remove old one
adamtagscherer Jul 28, 2023
5be9e24
feat(test): update dependencies and paths
paralta Aug 1, 2023
d41fcc2
feat(test): create or truncate database file
paralta Aug 1, 2023
6767ad5
feat(test): add integration test to makefile
paralta Aug 1, 2023
d9ed90e
fix: add scan subcommand to docker provider
paralta Aug 2, 2023
bb9baa0
feat(test): change vmclarity network to compose default network
paralta Aug 2, 2023
649320d
feat(test): add helpers file
paralta Aug 2, 2023
0494fe4
feat(test): add basic scan test
paralta Aug 2, 2023
fc8d150
feat(test): adjust to new microservice architecture
paralta Aug 3, 2023
3e5ac0a
feat(test): improve test logging
paralta Aug 4, 2023
643eec1
feat(test): only run sbom scan and scan alpine container
paralta Aug 4, 2023
9730339
feat(test): add default scan test
paralta Aug 7, 2023
dede595
feat(test): add failure types test
paralta Aug 7, 2023
815ee5a
feat(test): cleanup
paralta Aug 8, 2023
4f5a2b0
feat(test): rename to end to end test
paralta Aug 9, 2023
40544e9
feat(test): add new docker network for test services
paralta Aug 9, 2023
0985d59
feat(test): add container health checks
paralta Aug 9, 2023
844d152
feat(test): check healthServer of apiserver
paralta Aug 9, 2023
246415e
feat(test): clean up
paralta Aug 10, 2023
61dbc66
feat(test): ignore terminated assets
paralta Aug 10, 2023
87c22ae
feat(test): code review
paralta Aug 11, 2023
ba734b1
feat(test): use any operator in scan scope
paralta Aug 16, 2023
549430b
feat(test): add compose override file for testing
paralta Aug 16, 2023
778b71e
feat(test): use healthz endpoint in container healthcheck
paralta Aug 16, 2023
cec08bc
feat(test): bump go version
paralta Aug 16, 2023
295dc36
feat(test): make linter happy
paralta Aug 17, 2023
f268317
feat(test): code review changes
paralta Aug 18, 2023
babdcc5
feat(test): run push docker with e2e tests and use last commit tag
paralta Aug 21, 2023
d7ef8b0
feat(test): add e2e to make help
paralta Aug 25, 2023
3def20f
feat(test): only build not push images with make e2e
paralta Aug 25, 2023
0444e92
feat(test): fix uibackend healthcheck timeout
paralta Aug 28, 2023
2f47739
feat(test): use local scanner image if found
paralta Aug 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ api` to regenerate the model, client and server code.

### Testing End to End

`make e2e` can be used run all the integration tests in the repo.

For details on how to test VMClarity end to end please see the End to End
testing guide [here](docs/test_e2e.md).

Expand Down
10 changes: 9 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ LICENSEI_VERSION = 0.5.0
# thanks to https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
.PHONY: help
help: ## This help.
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_0-9-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)

.DEFAULT_GOAL := help

Expand Down Expand Up @@ -124,6 +124,14 @@ push-docker-uibackend: docker-uibackend ## Build and Push UI Backend Docker imag
test: ## Run Unit Tests
@go test ./...

.PHONY: e2e
e2e: docker-apiserver docker-cli docker-orchestrator ## Run go e2e test against code
@cd e2e && \
export APIServerContainerImage=${DOCKER_REGISTRY}/vmclarity-apiserver:${DOCKER_TAG} && \
export OrchestratorContainerImage=${DOCKER_REGISTRY}/vmclarity-orchestrator:${DOCKER_TAG} && \
export ScannerContainerImage=${DOCKER_REGISTRY}/vmclarity-cli:${DOCKER_TAG} && \
go test -v -failfast -test.v -test.paniconexit0 -timeout 2h -ginkgo.v .

.PHONY: clean-ui
clean-ui:
@(rm -rf ui/build ; echo "UI cleanup done" )
Expand Down
79 changes: 79 additions & 0 deletions e2e/abort_scan_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package e2e

import (
"fmt"
"time"

"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"

"github.com/openclarity/vmclarity/api/models"
"github.com/openclarity/vmclarity/pkg/shared/utils"
)

var _ = ginkgo.Describe("Aborting a scan", func() {
ginkgo.Context("which is running", func() {
ginkgo.It("should stop successfully", func(ctx ginkgo.SpecContext) {
ginkgo.By("applying a scan configuration")
apiScanConfig, err := client.PostScanConfig(ctx, GetDefaultScanConfig())
gomega.Expect(err).NotTo(gomega.HaveOccurred())

ginkgo.By("updating scan configuration to run now")
updateScanConfig := UpdateScanConfigToStartNow(apiScanConfig)
err = client.PatchScanConfig(ctx, *apiScanConfig.Id, updateScanConfig)
gomega.Expect(err).NotTo(gomega.HaveOccurred())

ginkgo.By("waiting until scan starts")
params := models.GetScansParams{
Filter: utils.PointerTo(fmt.Sprintf(
"scanConfig/id eq '%s' and state ne '%s' and state ne '%s'",
*apiScanConfig.Id,
models.ScanStateDone,
models.ScanStateFailed,
)),
}
var scans *models.Scans
gomega.Eventually(func() bool {
scans, err = client.GetScans(ctx, params)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
return len(*scans.Items) == 1
}, DefaultTimeout, time.Second).Should(gomega.BeTrue())

ginkgo.By("aborting a scan")
err = client.PatchScan(ctx, *(*scans.Items)[0].Id, &models.Scan{
State: utils.PointerTo(models.ScanStateAborted),
})
gomega.Expect(err).NotTo(gomega.HaveOccurred())

ginkgo.By("waiting until scan state changes to failed with aborted as state reason")
params = models.GetScansParams{
Filter: utils.PointerTo(fmt.Sprintf(
"scanConfig/id eq '%s' and state eq '%s' and stateReason eq '%s'",
*apiScanConfig.Id,
models.ScanStateFailed,
models.ScanStateReasonAborted,
)),
}
gomega.Eventually(func() bool {
scans, err = client.GetScans(ctx, params)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
return len(*scans.Items) == 1
}, DefaultTimeout, time.Second).Should(gomega.BeTrue())
})
})
})
92 changes: 92 additions & 0 deletions e2e/basic_scan_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package e2e

import (
"fmt"
"time"

"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"

"github.com/openclarity/vmclarity/api/models"
"github.com/openclarity/vmclarity/pkg/shared/utils"
)

var _ = ginkgo.Describe("Running a basic scan (only SBOM)", func() {
ginkgo.Context("which scans a docker container", func() {
ginkgo.It("should finish successfully", func(ctx ginkgo.SpecContext) {
ginkgo.By("waiting until test asset is found")
assetsParams := models.GetAssetsParams{
Filter: utils.PointerTo(fmt.Sprintf("terminatedOn eq null and %s", DefaultScope)),
}
gomega.Eventually(func() bool {
assets, err := client.GetAssets(ctx, assetsParams)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
return len(*assets.Items) == 1
}, DefaultTimeout, time.Second).Should(gomega.BeTrue())

ginkgo.By("applying a scan configuration")
apiScanConfig, err := client.PostScanConfig(
ctx,
GetCustomScanConfig(
&models.ScanFamiliesConfig{
Sbom: &models.SBOMConfig{
Enabled: utils.PointerTo(true),
},
},
DefaultScope,
600,
))
gomega.Expect(err).NotTo(gomega.HaveOccurred())

ginkgo.By("updating scan configuration to run now")
updateScanConfig := UpdateScanConfigToStartNow(apiScanConfig)
err = client.PatchScanConfig(ctx, *apiScanConfig.Id, updateScanConfig)
gomega.Expect(err).NotTo(gomega.HaveOccurred())

ginkgo.By("waiting until scan starts")
scanParams := models.GetScansParams{
Filter: utils.PointerTo(fmt.Sprintf(
"scanConfig/id eq '%s' and state ne '%s' and state ne '%s'",
*apiScanConfig.Id,
models.ScanStateDone,
models.ScanStateFailed,
)),
}
var scans *models.Scans
gomega.Eventually(func() bool {
scans, err = client.GetScans(ctx, scanParams)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
return len(*scans.Items) == 1
}, DefaultTimeout, time.Second).Should(gomega.BeTrue())

ginkgo.By("waiting until scan state changes to done")
scanParams = models.GetScansParams{
Filter: utils.PointerTo(fmt.Sprintf(
"scanConfig/id eq '%s' and state eq '%s'",
*apiScanConfig.Id,
models.ScanStateDone,
)),
}
gomega.Eventually(func() bool {
scans, err = client.GetScans(ctx, scanParams)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
return len(*scans.Items) == 1
}, time.Second*120, time.Second).Should(gomega.BeTrue())
})
})
})
72 changes: 72 additions & 0 deletions e2e/default_scan_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package e2e

import (
"fmt"
"time"

"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"

"github.com/openclarity/vmclarity/api/models"
"github.com/openclarity/vmclarity/pkg/shared/utils"
)

var _ = ginkgo.Describe("Running a default scan (SBOM, vulnerabilities and exploits)", func() {
ginkgo.Context("which scans a docker container", func() {
ginkgo.It("should finish successfully", func(ctx ginkgo.SpecContext) {
ginkgo.By("applying a scan configuration")
apiScanConfig, err := client.PostScanConfig(ctx, GetDefaultScanConfig())
gomega.Expect(err).NotTo(gomega.HaveOccurred())

ginkgo.By("updating scan configuration to run now")
updateScanConfig := UpdateScanConfigToStartNow(apiScanConfig)
err = client.PatchScanConfig(ctx, *apiScanConfig.Id, updateScanConfig)
gomega.Expect(err).NotTo(gomega.HaveOccurred())

ginkgo.By("waiting until scan starts")
scanParams := models.GetScansParams{
Filter: utils.PointerTo(fmt.Sprintf(
"scanConfig/id eq '%s' and state ne '%s' and state ne '%s'",
*apiScanConfig.Id,
models.ScanStateDone,
models.ScanStateFailed,
)),
}
var scans *models.Scans
gomega.Eventually(func() bool {
scans, err = client.GetScans(ctx, scanParams)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
return len(*scans.Items) == 1
}, DefaultTimeout, time.Second).Should(gomega.BeTrue())

ginkgo.By("waiting until scan state changes to done")
scanParams = models.GetScansParams{
Filter: utils.PointerTo(fmt.Sprintf(
"scanConfig/id eq '%s' and state eq '%s'",
*apiScanConfig.Id,
models.ScanStateDone,
)),
}
gomega.Eventually(func() bool {
scans, err = client.GetScans(ctx, scanParams)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
return len(*scans.Items) == 1
}, time.Second*120, time.Second).Should(gomega.BeTrue())
})
})
})
33 changes: 33 additions & 0 deletions e2e/docker-compose.override.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
services:
orchestrator:
# ...
volumes:
- type: bind
source: /var/run/docker.sock
target: /var/run/docker.sock
- type: bind
source: /tmp
target: /tmp

# Note(paralta): Override uibackend healthcheck is required because if server background recalculation fails the
# recalculation interval (backgroundRecalculationInterval) will be 15min. Plus, the uibackend is currently not
# covered by end-to-end tests.
uibackend:
ports:
- "8890:8890"
healthcheck:
test: ["CMD", "nc", "-z", "127.0.0.1", "8890"]
interval: 10s
retries: 60

alpine:
image: alpine:3.18.2
command: ["sleep", "infinity"]
networks:
- asset
labels:
scanconfig: test

networks:
asset:
name: ${COMPOSE_PROJECT_NAME}-asset
Loading
Loading