Skip to content

Commit

Permalink
Update e2e test
Browse files Browse the repository at this point in the history
1.Create a pod for test. And run the test cases in the container instead of VM.
2.Expand the test framework for golang SDK.
3.The test cases replay rtmrs and support ima.

Signed-off-by: hjh189 <jiahao.huang@intel.com>
  • Loading branch information
hjh189 committed Feb 5, 2024
1 parent 51bc94a commit 38515b9
Show file tree
Hide file tree
Showing 16 changed files with 568 additions and 87 deletions.
7 changes: 2 additions & 5 deletions test/e2e-test/ci-clean.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@ DEVICE_PLUGIN=localhost:5001/ccnp-device-plugin:latest
QUOTE=localhost:5001/ccnp-quote-server:latest
MEASUREMENT=localhost:5001/ccnp-measurement-server:latest
EVENTLOG=localhost:5001/ccnp-eventlog-server:latest
TEST_NODE=localhost:5001/ccnp-test-node:latest

kind delete cluster --name $CLUSTER_NAME
rm /run/ccnp/uds/*
docker stop $REG_NAME
docker rm $REG_NAME
sleep 1m
docker rmi ${DEVICE_PLUGIN} ${QUOTE} ${MEASUREMENT} ${EVENTLOG}
for i in $(docker images | grep "none" | awk '{print $3}');do
docker rmi "$i"
done
pip uninstall -y ccnp
docker rmi ${DEVICE_PLUGIN} ${QUOTE} ${MEASUREMENT} ${EVENTLOG} ${TEST_NODE}
67 changes: 63 additions & 4 deletions test/e2e-test/ci-e2e-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,70 @@ set -o errexit
: '
This is an E2E test script.
If you want to run the script , please run the ci-setup.sh script in advance to set up the ci test environment.
Please enter parameters to select the test case you want to run:
-a, run all test cases.
-s py/go, run python/golang sdk test cases, such as "-s py" means running python test cases.
'
PY_WORK_DIR='test/e2e-test/py-test'
GO_WORK_DIR='test/e2e-test/go-test/test-cases'
PY_FLAG=false
GO_FLAG=false


while getopts "as:" opt_name
do
case $opt_name in
a) PY_FLAG=true
GO_FLAG=true
echo "Run all test cases"
;;
s) parameter=$OPTARG
array=(${parameter//,/ })
for var in ${array[@]}
do
if [[ $var =~ "py" ]]
then
PY_FLAG=true
echo "Run py test cases"
elif [[ $var =~ "go" ]]
then
GO_FLAG=true
echo "Run go test cases"
fi
done
;;
?) echo "Invalid input"
      ;;
esac
done




for i in {1..3}
do
POD_NAME=$(kubectl get po | grep ccnp-test-node | grep Running | awk '{ print $1 }')
if [[ -z "$POD_NAME" ]]
then
sleep 2
echo "Retrying $i time ..."
else
break
fi
done



WORK_DIR=$(cd "$(dirname "$0")"; pwd)
#Run python E2E test cases
if $PY_FLAG
then
kubectl exec -it "$POD_NAME" -- pytest -v ${PY_WORK_DIR}
fi

#Run E2E test cases
pip install pytest pytdxattest
pytest "${WORK_DIR}/test_eventlog.py" "${WORK_DIR}/test_tdquote.py" "${WORK_DIR}/test_tdreport.py"
#Run golang E2E test cases
if $GO_FLAG
then
kubectl exec -it "$POD_NAME" -- bash -c "pushd ${GO_WORK_DIR};go test -v;popd "
fi

23 changes: 11 additions & 12 deletions test/e2e-test/ci-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@ This is a script for setting up the CCNP ci environment. If you want to run the
1 According to the CCNP documentation, create a TDVM
2 Install helm and kind on the TDVM
3 Follow the CCNP documentation to pre-configure the TDVM,including modifying the file "/etc/udev/rules.d/90-tdx.rules" and creating the folder "/run/ccnp/uds"
4 Git clone CCNP and run this script
4 Run this script
'

CLUSTER_NAME=my-cluster
KIND_CONFIG=kind-config.yaml
KIND_CONFIG=profile/kind-config.yaml
DEVICE_PLUGIN=localhost:5001/ccnp-device-plugin:latest
QUOTE=localhost:5001/ccnp-quote-server:latest
MEASUREMENT=localhost:5001/ccnp-measurement-server:latest
EVENTLOG=localhost:5001/ccnp-eventlog-server:latest
TEST_NODE=localhost:5001/ccnp-test-node:latest
REG_NAME=kind-registry
REG_PORT=5001
REPO_CONFIGMAP=repo-configmap.yaml
REPO_CONFIGMAP=profile/repo-configmap.yaml
LOCAL_REPO=localhost:5001
DOCKER_REPO=docker.io/library
NFD_URL=https://kubernetes-sigs.github.io/node-feature-discovery/charts
Expand All @@ -37,7 +38,6 @@ create_file(){
if [ ! -e "$1" ];then
touch "$1"
fi

}


Expand Down Expand Up @@ -79,15 +79,20 @@ docker build --build-arg http_proxy="$HTTP_PROXY" --build-arg https_proxy="$HTTP
--build-arg no_proxy="$NO_PROXY" -t $EVENTLOG -f container/ccnp-eventlog-server/Dockerfile .
docker build --build-arg http_proxy="$HTTP_PROXY" --build-arg https_proxy="$HTTPS_PROXY" \
--build-arg no_proxy="$NO_PROXY" -t $DEVICE_PLUGIN -f container/ccnp-device-plugin/Dockerfile .
docker build --build-arg http_proxy="$HTTP_PROXY" --build-arg https_proxy="$HTTPS_PROXY" \
--build-arg no_proxy="$NO_PROXY" -t $TEST_NODE -f test/e2e-test/profile/Dockerfile .


docker push ${DEVICE_PLUGIN}
docker push ${QUOTE}
docker push ${MEASUREMENT}
docker push ${EVENTLOG}
docker push ${TEST_NODE}

sed -i "s#${DOCKER_REPO}#${LOCAL_REPO}#g" deployment/manifests/*
sed -i "s#${DOCKER_REPO}#${LOCAL_REPO}#g" device-plugin/ccnp-device-plugin/deploy/helm/ccnp-device-plugin/values.yaml
sed -i "s#${DOCKER_REPO}#${LOCAL_REPO}#g" test/e2e-test/profile/ccnp-test-node.yaml


#Deploy CCNP Dependencies
helm repo add nfd $NFD_URL
Expand All @@ -101,14 +106,8 @@ kubectl create -f deployment/manifests/namespace.yaml
kubectl create -f deployment/manifests/eventlog-server-deployment.yaml
kubectl create -f deployment/manifests/measurement-server-deployment.yaml
kubectl create -f deployment/manifests/quote-server-deployment.yaml

kubectl create -f test/e2e-test/profile/ccnp-test-node.yaml
#Wait for all pods and services to be ready
sleep 2m
sleep 1m

#Install SDK
pushd sdk/python3/
pip install -r requirements.txt
pip install .
popd
popd

22 changes: 22 additions & 0 deletions test/e2e-test/go-test/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module gosdk-test

go 1.20

require (
github.com/golang/protobuf v1.5.3 // indirect
github.com/intel/confidential-cloud-native-primitives/service/eventlog-server v0.0.0-20240131020930-fcd202dd676e // indirect
github.com/pkg/errors v0.9.1 // indirect
golang.org/x/net v0.18.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect
google.golang.org/grpc v1.61.0 // indirect
google.golang.org/protobuf v1.32.0 // indirect
)

require (
ccnp v0.0.0-00010101000000-000000000000
github.com/intel/confidential-cloud-native-primitives/sdk/golang/ccnp v0.0.0-20240131020930-fcd202dd676e
)

replace ccnp => ../../../sdk/golang/ccnp
26 changes: 26 additions & 0 deletions test/e2e-test/go-test/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/intel/confidential-cloud-native-primitives/sdk/golang/ccnp v0.0.0-20240131020930-fcd202dd676e h1:DaaWyQatEN+KQzrmT2xWTY5RMkqnPqOcbNq/LgBqv8M=
github.com/intel/confidential-cloud-native-primitives/sdk/golang/ccnp v0.0.0-20240131020930-fcd202dd676e/go.mod h1:0dSZ/QSICtHucjtiP8yb8ouQU7m//ZPd/dsMehE8CrU=
github.com/intel/confidential-cloud-native-primitives/service/eventlog-server v0.0.0-20240131020930-fcd202dd676e h1:/FUVfJrpfbtHoaqrYRyGwovr8UGzohvEP89qBHeIW9Q=
github.com/intel/confidential-cloud-native-primitives/service/eventlog-server v0.0.0-20240131020930-fcd202dd676e/go.mod h1:u9nIX7H+etWAv/h9YKWs3gspzVDPMSgEJj83tc5YuZQ=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA=
google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0=
google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
117 changes: 117 additions & 0 deletions test/e2e-test/go-test/test-cases/gosdk_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Define some structures and functions to support golang SDK test.

package gosdk_test

import (
"ccnp/eventlog"
"log"
"strings"
"crypto/sha512"
"encoding/hex"
"io/ioutil"
"strconv"
)


const rtmrCount int = 4
const rtmrLength int = 48
const runtimeRegister uint32 = 2
const imaFile string = "/run/security/integrity/ima/ascii_runtime_measurements"

type rtmr struct{
data []byte
}


type eventLogActor struct{
bootTimeEventlogs []eventlog.CCEventLogEntry
runTimeEventlogs []string
}


func newEventLogActor() *eventLogActor {
bootTimeEventlogs,err := eventlog.GetPlatformEventlog()
if err != nil {
log.Fatalf("Get eventlog error: %v", err)
}

imaFlag := true
f, err := ioutil.ReadFile("/proc/cmdline")
if err != nil {
log.Fatalf("Get cmdline error: %v", err)
}
cmdline := string(f)
if !strings.Contains(cmdline, "ima_hash=sha384"){
imaFlag = false
}

var runTimeEventlogs []string
if imaFlag == true{
f, err := ioutil.ReadFile(imaFile)
if err != nil {
log.Fatalf("Read file: %v error: %v", imaFile, err)
}
imaStr := string(f)
for _, runTimeEventlog := range strings.Split(imaStr, "\n") {
runTimeEventlogs = append(runTimeEventlogs, runTimeEventlog)
}
}

return &eventLogActor{bootTimeEventlogs: bootTimeEventlogs,runTimeEventlogs: runTimeEventlogs}
}


func (e eventLogActor) replayBootTime(index uint32) *rtmr {
rtmrVal := make([]byte,rtmrLength)


for _,bootTimeEventlog := range e.bootTimeEventlogs{
if bootTimeEventlog.RegIdx == index {
var digestHex string
digest := string(bootTimeEventlog.Digest)
for _, val := range strings.Split(strings.Trim(digest, "[]"), " ") {
valInt,_ := strconv.Atoi(val)
valHex := strconv.FormatInt(int64(valInt), 16)
if len(valHex) == 1 {
valHex = "0" + valHex
}
digestHex = digestHex+valHex
}

h := sha512.New384()
rtmrValHex := hex.EncodeToString(rtmrVal)
combVal,_ := hex.DecodeString(rtmrValHex+digestHex)
h.Write(combVal)
rtmrVal = h.Sum(nil)
}}

return &rtmr{data:rtmrVal}
}

func (e eventLogActor) replayRunTime(baseRtmr *rtmr) *rtmr {
extendVal := baseRtmr.data
for _,runTimeEventlog := range e.runTimeEventlogs{
extendValHex := hex.EncodeToString(extendVal)
elements := strings.Fields(runTimeEventlog)
if len(elements) != 0{
h := sha512.New384()
combVal,_:=hex.DecodeString(extendValHex + elements[1])
h.Write(combVal)
extendVal = h.Sum(nil)
}
}

return &rtmr{data:extendVal}
}



func (e eventLogActor) replay(index uint32) []byte {
rtmrValue := e.replayBootTime(index)
if index == runtimeRegister && len(e.runTimeEventlogs) != 0{
rtmrValue = e.replayRunTime(rtmrValue)
}
return rtmrValue.data
}


52 changes: 52 additions & 0 deletions test/e2e-test/go-test/test-cases/rtmrs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
RTMR test:
1. Fetch boot time event logs using CCNP sdk and fetch runtime event logs(from IMA) in kernel memory
2. Re-calcuate the overall digest
3. Fetch measurements using CCNP sdk
4. Compare the recalculated values with the rtmrs in the measurements
*/

package gosdk_test

import (
"github.com/intel/confidential-cloud-native-primitives/sdk/golang/ccnp/measurement"
pb "github.com/intel/confidential-cloud-native-primitives/sdk/golang/ccnp/measurement/proto"
"testing"
"bytes"
)

func TestRtmr(t *testing.T) {
t.Run("rtmr0", func(t *testing.T) {
eventLogActor := newEventLogActor()
replayVal0 := eventLogActor.replay(0)
val0,_ := measurement.GetPlatformMeasurement(measurement.WithMeasurementType(pb.CATEGORY_TDX_RTMR), measurement.WithRegisterIndex(0))
if !bytes.Equal(replayVal0, val0.(measurement.TDXRtmrInfo).TDXRtmrRaw){
t.Error("rtmr0 replay:fail")
}})

t.Run("rtmr1", func(t *testing.T) {
eventLogActor := newEventLogActor()
replayVal1 := eventLogActor.replay(1)
val1,_ := measurement.GetPlatformMeasurement(measurement.WithMeasurementType(pb.CATEGORY_TDX_RTMR), measurement.WithRegisterIndex(1))
if !bytes.Equal(replayVal1, val1.(measurement.TDXRtmrInfo).TDXRtmrRaw){
t.Error("rtmr1 replay:fail")
}})
t.Run("rtmr2", func(t *testing.T) {
eventLogActor := newEventLogActor()
replayVal2 := eventLogActor.replay(2)
val2,_ := measurement.GetPlatformMeasurement(measurement.WithMeasurementType(pb.CATEGORY_TDX_RTMR), measurement.WithRegisterIndex(2))
if !bytes.Equal(replayVal2, val2.(measurement.TDXRtmrInfo).TDXRtmrRaw){
t.Error("rtmr2 replay:fail")
}})

t.Run("rtmr3", func(t *testing.T) {
eventLogActor := newEventLogActor()
replayVal3 := eventLogActor.replay(3)
val3,_ := measurement.GetPlatformMeasurement(measurement.WithMeasurementType(pb.CATEGORY_TDX_RTMR), measurement.WithRegisterIndex(3))
if !bytes.Equal(replayVal3, val3.(measurement.TDXRtmrInfo).TDXRtmrRaw){
t.Error("rtmr3 replay:fail")
}})


}

Loading

0 comments on commit 38515b9

Please sign in to comment.