-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Shahriyar Jalayeri <[email protected]>
- Loading branch information
Showing
7 changed files
with
285 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
DEBUG ?= "debug" | ||
|
||
# HOSTARCH is the host architecture | ||
# ARCH is the target architecture | ||
# we need to keep track of them separately | ||
HOSTARCH ?= $(shell uname -m) | ||
HOSTOS ?= $(shell uname -s | tr A-Z a-z) | ||
|
||
# canonicalized names for host architecture | ||
override HOSTARCH := $(subst aarch64,arm64,$(subst x86_64,amd64,$(HOSTARCH))) | ||
|
||
# unless otherwise set, I am building for my own architecture, i.e. not cross-compiling | ||
# and for my OS | ||
ARCH ?= $(HOSTARCH) | ||
OS ?= $(HOSTOS) | ||
|
||
# canonicalized names for target architecture | ||
override ARCH := $(subst aarch64,arm64,$(subst x86_64,amd64,$(ARCH))) | ||
|
||
WORKDIR ?= $(CURDIR)/../../dist | ||
TESTDIR := tests/$(shell basename $(CURDIR)) | ||
BINDIR := $(WORKDIR)/bin | ||
DATADIR := $(WORKDIR)/$(TESTDIR)/ | ||
BIN := eden | ||
LOCALBIN := $(BINDIR)/$(BIN)-$(OS)-$(ARCH) | ||
TESTNAME := eden.sec | ||
TESTBIN := $(TESTNAME).test | ||
TESTSCN := $(TESTNAME).tests.txt | ||
LOCALTESTBIN := $(TESTBIN)-$(OS)-$(ARCH) | ||
LINKDIR := ../../tests/sec | ||
|
||
.DEFAULT_GOAL := help | ||
|
||
clean: | ||
rm -rf $(LOCALTESTBIN) $(BINDIR)/$(TESTBIN) $(WORKDIR)/$(TESTSCN) $(CURDIR)/$(TESTBIN) $(BINDIR)/$(TESTBIN) | ||
|
||
$(BINDIR): | ||
mkdir -p $@ | ||
$(DATADIR): | ||
mkdir -p $@ | ||
|
||
test_sec: | ||
go test sec_test.go common.go -v -count=1 -timeout 3000s | ||
|
||
test: | ||
$(LOCALBIN) test $(CURDIR) -v $(DEBUG) | ||
|
||
build: setup | ||
|
||
testbin: $(TESTBIN) | ||
$(LOCALTESTBIN): $(BINDIR) *.go | ||
CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) go test -c -ldflags "-s -w" -o $@ *.go | ||
|
||
$(TESTBIN): $(LOCALTESTBIN) | ||
ln -sf $(LOCALTESTBIN) $(CURDIR)/$(TESTBIN) | ||
|
||
setup: testbin $(BINDIR) $(DATADIR) | ||
cp -a $(LOCALTESTBIN) $(CURDIR)/$(TESTBIN) $(BINDIR) | ||
cp -a *.yml $(TESTSCN) $(DATADIR) | ||
|
||
.PHONY: test build setup clean all testbin | ||
|
||
help: | ||
@echo "EDEN is the harness for testing EVE and ADAM" | ||
@echo | ||
@echo "This Makefile automates commons tasks of EDEN testing" | ||
@echo | ||
@echo "Commonly used maintenance and development targets:" | ||
@echo " build build test-binary (OS and ARCH options supported, for ex. OS=linux ARCH=arm64)" | ||
@echo " setup setup of test environment" | ||
@echo " test run tests" | ||
@echo " clean cleanup of test harness" | ||
@echo | ||
@echo "You need install requirements for EVE (look at https://github.com/lf-edge/eve#install-dependencies)." | ||
@echo "You need access to docker socket and installed qemu packages." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
eden: | ||
# test binary | ||
test-bin: "eden.sec.test" | ||
|
||
# test scenario | ||
test-scenario: "eden.sec.tests.txt" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
eden.sec.test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package sec_test | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"os" | ||
"strings" | ||
|
||
"github.com/lf-edge/eden/pkg/defaults" | ||
"github.com/lf-edge/eden/pkg/openevec" | ||
"github.com/lf-edge/eden/pkg/utils" | ||
) | ||
|
||
type remoteNode struct { | ||
openEVEC *openevec.OpenEVEC | ||
} | ||
|
||
func getOpenEVEC() *openevec.OpenEVEC { | ||
edenConfigEnv := os.Getenv(defaults.DefaultConfigEnv) | ||
configName := utils.GetConfig(edenConfigEnv) | ||
|
||
viperCfg, err := openevec.FromViper(configName, "debug") | ||
if err != nil { | ||
return nil | ||
} | ||
|
||
return openevec.CreateOpenEVEC(viperCfg) | ||
} | ||
|
||
func createRemoteNode() *remoteNode { | ||
evec := getOpenEVEC() | ||
if evec == nil { | ||
return nil | ||
} | ||
|
||
return &remoteNode{openEVEC: evec} | ||
} | ||
|
||
func (node *remoteNode) runCommand(command string) ([]byte, error) { | ||
realStdout := os.Stdout | ||
r, w, err := os.Pipe() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
os.Stdout = w | ||
|
||
// unfortunately, we can't capture command return value from SSHEve | ||
err = node.openEVEC.SSHEve(command) | ||
|
||
os.Stdout = realStdout | ||
w.Close() | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
out, _ := io.ReadAll(r) | ||
return out, nil | ||
} | ||
|
||
func (node *remoteNode) fileExists(fileName string) (bool, error) { | ||
command := fmt.Sprintf("if stat \"%s\"; then echo \"1\"; else echo \"0\"; fi", fileName) | ||
out, err := node.runCommand(command) | ||
if err != nil { | ||
return false, err | ||
} | ||
|
||
if strings.TrimSpace(string(out)) == "0" { | ||
return false, nil | ||
} | ||
|
||
return true, nil | ||
} | ||
|
||
func (node *remoteNode) readFile(fileName string) ([]byte, error) { | ||
exist, err := node.fileExists(fileName) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if !exist { | ||
return nil, fmt.Errorf("file %s does not exist", fileName) | ||
} | ||
|
||
command := fmt.Sprintf("cat %s", fileName) | ||
return node.runCommand(command) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package sec_test | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"strings" | ||
"testing" | ||
"time" | ||
|
||
log "github.com/sirupsen/logrus" | ||
|
||
"github.com/lf-edge/eden/pkg/device" | ||
"github.com/lf-edge/eden/pkg/projects" | ||
"github.com/lf-edge/eden/pkg/tests" | ||
) | ||
|
||
var ( | ||
tc *projects.TestContext | ||
rnode *remoteNode | ||
) | ||
|
||
// TestMain is used to provide setup and teardown for the rest of the | ||
// tests. As part of setup we make sure that context has a slice of | ||
// EVE instances that we can operate on. For any action, if the instance | ||
// is not specified explicitly it is assumed to be the first one in the slice | ||
func TestMain(m *testing.M) { | ||
log.Println("Security Test Suite started") | ||
|
||
tests.TestArgsParse() | ||
|
||
tc = projects.NewTestContext() | ||
|
||
projectName := fmt.Sprintf("%s_%s", "TestSecurity", time.Now()) | ||
|
||
// Registering our own project namespace with controller for easy cleanup | ||
tc.InitProject(projectName) | ||
|
||
// Create representation of EVE instances (based on the names | ||
// or UUIDs that were passed in) in the context. This is the first place | ||
// where we're using zcli-like API: | ||
for _, node := range tc.GetNodeDescriptions() { | ||
edgeNode := node.GetEdgeNode(tc) | ||
if edgeNode == nil { | ||
// Couldn't find existing edgeNode record in the controller. | ||
// Need to create it from scratch now: | ||
// this is modeled after: zcli edge-node create <name> | ||
// --project=<project> --model=<model> [--title=<title>] | ||
// ([--edge-node-certificate=<certificate>] | | ||
// [--onboarding-certificate=<certificate>] | | ||
// [(--onboarding-key=<key> --serial=<serial-number>)]) | ||
// [--network=<network>...] | ||
// | ||
// XXX: not sure if struct (giving us optional fields) would be better | ||
edgeNode = tc.NewEdgeNode(tc.WithNodeDescription(node), tc.WithCurrentProject()) | ||
} else { | ||
// make sure to move EdgeNode to the project we created, again | ||
// this is modeled after zcli edge-node update <name> [--title=<title>] | ||
// [--lisp-mode=experimental|default] [--project=<project>] | ||
// [--clear-onboarding-certs] [--config=<key:value>...] [--network=<network>...] | ||
edgeNode.SetProject(projectName) | ||
} | ||
|
||
tc.ConfigSync(edgeNode) | ||
|
||
// finally we need to make sure that the edgeNode is in a state that we need | ||
// it to be, before the test can run -- this could be multiple checks on its | ||
// status, but for example: | ||
if edgeNode.GetState() == device.NotOnboarded { | ||
log.Fatal("Node is not onboarded now") | ||
} | ||
|
||
// this is a good node -- lets add it to the test context | ||
tc.AddNode(edgeNode) | ||
} | ||
|
||
tc.StartTrackingState(false) | ||
|
||
// create a remote node | ||
rnode = createRemoteNode() | ||
if rnode == nil { | ||
log.Fatal("Can't initlize the remote node") | ||
} | ||
|
||
// we now have a situation where TestContext has enough EVE nodes known | ||
// for the rest of the tests to run. So run them: | ||
res := m.Run() | ||
|
||
// Finally, we need to cleanup whatever objects may be in in the | ||
// project we created and then we can exit | ||
os.Exit(res) | ||
} | ||
|
||
func TestAppArmorEnabled(t *testing.T) { | ||
log.Println("TestAppArmorEnabled started") | ||
defer log.Println("TestAppArmorEnabled finished") | ||
t.Parallel() | ||
|
||
edgeNode := tc.GetEdgeNode(tc.WithTest(t)) | ||
tc.WaitForState(edgeNode, 60) | ||
|
||
out, err := rnode.readFile("/sys/module/apparmor/parameters/enabled") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
exits := strings.TrimSpace(string(out)) | ||
if exits != "Y" { | ||
t.Fatal("AppArmor is not enabled") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
test eden.sec.test |