Skip to content

Commit

Permalink
e2e tests: Added the e2e test folder and included the docker compose …
Browse files Browse the repository at this point in the history
…file with Everest configurations
  • Loading branch information
usuletw022 committed Mar 20, 2024
1 parent 9f5b969 commit 3936fde
Show file tree
Hide file tree
Showing 48 changed files with 3,207 additions and 0 deletions.
19 changes: 19 additions & 0 deletions e2e-tests/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.PHONY: up
up: register-cs setup-rfid setup-contract
OCPP_VERSION=ocpp docker-compose --profile everest up

.PHONY: test
test: # password 123456
websocat --client-pkcs12-der ./config/certificates/cs001.pem --client-pkcs12-passwd 123456 wss://localhost:443

.PHONY: setup-rfid
setup-rfid:
curl -i http://localhost:9410/api/v0/token -H 'content-type: application/json' -d '{"countryCode": "GB","partyId": "TWK","type": "RFID","uid": "DEADBEEF","contractId": "GBTWK012345678V","issuer": "Thoughtworks","valid": true,"cacheMode": "ALWAYS"}'

.PHONY: setup-contract
setup-contract:
curl -i http://localhost:9410/api/v0/token -H 'content-type: application/json' -d '{"countryCode": "GB","partyId": "TWK","type": "RFID","uid": "EMP77TWTW99999","contractId": "GBTWK012345678V","issuer": "Thoughtworks","valid": true,"cacheMode": "ALWAYS"}'

.PHONY: register-cs
register-cs:
curl -i http://localhost:9410/api/v0/cs/cs001 -H 'content-type: application/json' -d '{"securityProfile":2}'
15 changes: 15 additions & 0 deletions e2e-tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# End-to-End test

We currently use two different versions of EVerest and the MQTT API for RFID authorisation
is different between them: if using the older "v5" image (the default):

```shell
$ NO_AUTH_TOKEN_TYPE_PREFIX=1 go test -v ./... -count=1
```

Otherwise,

```shell
$ go test -v ./... -count=1
```

56 changes: 56 additions & 0 deletions e2e-tests/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
version: "3.5"

networks:
default:
name: maeve-csms
external: true

services:
mqtt-server:
image: ghcr.io/everest/everest-demo/mqtt-server:0.0.10
logging:
driver: none
ports:
- "1884:1883"
- "9001:9000"
user: "10000:10000"
healthcheck:
test: [ "CMD-SHELL", "timeout 5 mosquitto_sub -t '$$SYS/#' -C 1 | grep -v Error || exit 1" ]
interval: 10s
timeout: 10s
retries: 3

manager:
image: ghcr.io/everest/everest-demo/manager:0.0.10
depends_on:
- mqtt-server
environment:
MQTT_SERVER_ADDRESS: mqtt-server
entrypoint: "sh ./build/run-scripts/run-sil-${OCPP_VERSION}.sh"
sysctls:
- net.ipv6.conf.all.disable_ipv6=0
volumes:
- type: bind
source: ./everest/config/everest
target: /ext/source/config
- type: bind
source: ./everest/config/everest/ocpp/OCPP
target: /workspace/dist/share/everest/modules/OCPP
- type: bind
source: ./everest/config/everest/ocpp/OCPP201
target: /workspace/dist/share/everest/modules/OCPP201
- type: bind
source: ./everest/config/everest/certs
target: /workspace/dist/etc/everest/certs

nodered:
image: ghcr.io/everest/everest-demo/nodered:0.0.10
depends_on:
- mqtt-server
environment:
- MQTT_SERVER_ADDRESS=mqtt-server
- FLOWS=/config/config-sil-two-evse-flow.json
ports:
- 1880:1880
sysctls:
- net.ipv6.conf.all.disable_ipv6=0
166 changes: 166 additions & 0 deletions e2e-tests/end_to_end_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package main

import (
"fmt"
mqtt "github.com/eclipse/paho.mqtt.golang"
"os"
"sync"
"testing"
"time"
)

func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool {
c := make(chan struct{})
go func() {
defer close(c)
wg.Wait()
}()
select {
case <-c:
return false // completed normally
case <-time.After(timeout):
return true // timed out
}
}

func shutdownBrokerConnection(t *testing.T, client mqtt.Client, wg *sync.WaitGroup) {
defer client.Disconnect(0)

t.Log("unplugging...")
wg.Add(1)
tok := client.Publish("everest_external/nodered/1/carsim/cmd/modify_charging_session", 0, false, "unplug")
if tok.WaitTimeout(1 * time.Second); tok.Error() != nil {
t.Errorf("failed to publish unplug to topic: %v", tok.Error())
}
timedOut := waitTimeout(wg, 5*time.Second)
if timedOut {
t.Errorf("timed out waiting for unplug to complete")
}
}

func setupBrokerConnection(t *testing.T, wg *sync.WaitGroup) (mqtt.Client, func()) {
brokerAddr := os.Getenv("MQTT_BROKER_ADDR")
if brokerAddr == "" {
brokerAddr = "localhost:1884"
}

opts := mqtt.NewClientOptions()
opts.AddBroker(brokerAddr)

client := mqtt.NewClient(opts)
if token := client.Connect(); token.WaitTimeout(2*time.Second) && token.Error() != nil {
t.Fatalf("failed to connect to MQTT broker: %v", token.Error())
}

return client, func() {
shutdownBrokerConnection(t, client, wg)
}
}

func TestRFIDCharge(t *testing.T) {
// we currently use two different versions of EVerest and the MQTT API for RFID authorisation is different
// between them: if using the older "v5" image (the default) set the environment variable NO_AUTH_TOKEN_TYPE_PREFIX

wg := sync.WaitGroup{}

client, shutdown := setupBrokerConnection(t, &wg)
defer shutdown()

state := "Unset"

tok := client.Subscribe("everest_external/nodered/1/state/state_string", 0, func(client mqtt.Client, msg mqtt.Message) {
t.Logf("charger status changed to %s\n", msg.Payload())

switch string(msg.Payload()) {
case "Wait for Auth":
state = string(msg.Payload())
wg.Done()
case "Charging":
state = string(msg.Payload())
wg.Done()
case "Idle":
state = string(msg.Payload())
wg.Done()
}
})
if tok.WaitTimeout(1 * time.Second); tok.Error() != nil {
t.Fatalf("failed to subscribe to topic: %v", tok.Error())
}

wg.Add(1)
t.Logf("plug in...")
tok = client.Publish("everest_external/nodered/1/carsim/cmd/execute_charging_session", 0, false,
"sleep 1;iec_wait_pwr_ready;sleep 1;draw_power_regulated 16,3;sleep 5")

if tok.WaitTimeout(1 * time.Second); tok.Error() != nil {
t.Fatalf("failed to publish start charge to topic: %v", tok.Error())
}

timedOut := waitTimeout(&wg, 5*time.Second)
if timedOut {
t.Errorf("timed out waiting for ready to authorise")
}
if state != "Wait for Auth" {
t.Fatalf("expected state to be Wait for Auth, got %s", state)
}

wg.Add(1)
t.Logf("authorise charge...")
tok = client.Publish("everest_api/dummy_token_provider/cmd/provide", 0, false,
fmt.Sprintf("{\"id_token\":\"DEADBEEF\",\"authorization_type\":\"RFID\",\"prevalidated\":false,\"connectors\":[1]}"))
if tok.WaitTimeout(1 * time.Second); tok.Error() != nil {
t.Fatalf("failed to publish authorise to topic: %v", tok.Error())
}

timedOut = waitTimeout(&wg, 5*time.Second)
if timedOut {
t.Errorf("timed out waiting for authorise to complete")
}
if state != "Charging" {
t.Fatalf("expected state to be Charging, got %s", state)
}
}

func TestISO15118Charge(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
wg := sync.WaitGroup{}

client, shutdown := setupBrokerConnection(t, &wg)
defer shutdown()

state := "Unset"

tok := client.Subscribe("everest_external/nodered/1/state/state_string", 0, func(client mqtt.Client, msg mqtt.Message) {
t.Logf("charger status changed to %s\n", msg.Payload())

switch string(msg.Payload()) {
case "PrepareCharging":
state = string(msg.Payload())
wg.Done()
case "Idle":
state = string(msg.Payload())
wg.Done()
}
})
if tok.WaitTimeout(1 * time.Second); tok.Error() != nil {
t.Fatalf("failed to subscribe to topic: %v", tok.Error())
}

wg.Add(1)
t.Logf("plug in...")
tok = client.Publish("everest_external/nodered/1/carsim/cmd/execute_charging_session", 0, false,
"sleep 1;iso_wait_slac_matched;iso_start_v2g_session Contract,AC_three_phase_core;iso_wait_pwr_ready;iso_draw_power_regulated 16,3;sleep 36000")
if tok.WaitTimeout(1 * time.Second); tok.Error() != nil {
t.Fatalf("failed to publish start charge to topic: %v", tok.Error())
}

timedOut := waitTimeout(&wg, 15*time.Second)
if timedOut {
t.Errorf("timed out waiting for charge to start")
}
if state != "PrepareCharging" {
t.Fatalf("expected state to be PrepareCharging, got %s", state)
}
}
47 changes: 47 additions & 0 deletions e2e-tests/everest/config/certificates/HUBOpenProvCert001.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
-----BEGIN CERTIFICATE-----
MIIB9jCCAZygAwIBAgIQXAGaGc0odduhH6YnK05NazAKBggqhkjOPQQDAjBDMQsw
CQYDVQQGEwJERTEVMBMGA1UEChMMSHViamVjdCBHbWJIMR0wGwYDVQQDExRNTyBT
dWIyIENBIFFBIEcxLjIuMTAeFw0yMzA1MjMxMjU1NTNaFw0yNDAzMDEwMDAwMDBa
MCsxEDAOBgNVBAoTB0h1YmplY3QxFzAVBgNVBAMTDkVNUDc3VFdUVzAwMDAyMFkw
EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUVJxF0Z81GW4LZ3fnvC+z5fn7QvPe+nx
ZBOGtzpB6RRmafqwTL9ctzWMMkaB6nuIUyyTKR0Rs+XKYJeToK7S8qOBiTCBhjAP
BgNVHRMBAf8EBTADAQEAMBEGA1UdDgQKBAhGBfp1bBhxXDATBgNVHSMEDDAKgAhF
LmmhNiJsSDA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUHMAGGH2h0dHA6Ly9vY3Nw
LXFhLmh1YmplY3QuY29tOjgwODAwDgYDVR0PAQH/BAQDAgPoMAoGCCqGSM49BAMC
A0gAMEUCIBV5rlKEeHjernJPfzxA3HyPH742YcS8oEmUlWccrH62AiEAln/HGazM
NZqhoS5SSscViysAOQGvvcjHMKucJ5CjdLg=
-----END CERTIFICATE-----
subject=/C=DE/O=Hubject GmbH/CN=MO Sub2 CA QA G1.2.1
issuer=/C=DE/O=Hubject GmbH/CN=MO Sub1 CA QA G1.2
-----BEGIN CERTIFICATE-----
MIICDzCCAbWgAwIBAgIQXd9CzQy8+VxpQt9IwNrOETAKBggqhkjOPQQDAjBBMQsw
CQYDVQQGEwJERTEVMBMGA1UEChMMSHViamVjdCBHbWJIMRswGQYDVQQDExJNTyBT
dWIxIENBIFFBIEcxLjIwHhcNMjIwNDEwMjE1OTU5WhcNMzIwNDEwMjE1OTU5WjBD
MQswCQYDVQQGEwJERTEVMBMGA1UEChMMSHViamVjdCBHbWJIMR0wGwYDVQQDExRN
TyBTdWIyIENBIFFBIEcxLjIuMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGRs
p5TTDIGpB+PEwmeG8D7Pgo/WN3U35Rxhe5ttLLlyF2jlmtOPHeHxWgGb0AO7H3L6
nso0A7Nn2KfDP8tG+OujgYwwgYkwEgYDVR0TAQH/BAgwBgEB/wIBADARBgNVHQ4E
CgQIRS5poTYibEgwEwYDVR0jBAwwCoAISw94EhgPO18wOwYIKwYBBQUHAQEELzAt
MCsGCCsGAQUFBzABhh9odHRwOi8vb2NzcC1xYS5odWJqZWN0LmNvbTo4MDgwMA4G
A1UdDwEB/wQEAwIBxjAKBggqhkjOPQQDAgNIADBFAiBqFxXTwnpm0eEgBPj/Px0k
aEvZWdyZPm7BLJVJM6fT3QIhAKZPDhuau2DcN9xrrRPqqZLjfqPSMWw1D0VlCTqC
uv2k
-----END CERTIFICATE-----

subject=/C=DE/O=Hubject GmbH/CN=MO Sub1 CA QA G1.2
issuer=/C=DE/O=Hubject GmbH/DC=V2G/CN=V2G Root CA QA G1
-----BEGIN CERTIFICATE-----
MIICIjCCAcegAwIBAgIQIOuk+8fAbyXQizBVpSI55zAKBggqhkjOPQQDAjBVMQsw
CQYDVQQGEwJERTEVMBMGA1UEChMMSHViamVjdCBHbWJIMRMwEQYKCZImiZPyLGQB
GRYDVjJHMRowGAYDVQQDExFWMkcgUm9vdCBDQSBRQSBHMTAeFw0yMjA0MDcxNDEz
MDdaFw00MjA0MDcxNDEzMDdaMEExCzAJBgNVBAYTAkRFMRUwEwYDVQQKEwxIdWJq
ZWN0IEdtYkgxGzAZBgNVBAMTEk1PIFN1YjEgQ0EgUUEgRzEuMjBZMBMGByqGSM49
AgEGCCqGSM49AwEHA0IABLWnWSw4NPNInduDQp6H0IFgeY0WtO0F3utqV191XLIe
spoAoSIz7s4Vhf+BhbbeX+UyftbGDp2m9EjGIBhog+mjgYwwgYkwEgYDVR0TAQH/
BAgwBgEB/wIBATARBgNVHQ4ECgQISw94EhgPO18wEwYDVR0jBAwwCoAIS0X/giX8
EJYwOwYIKwYBBQUHAQEELzAtMCsGCCsGAQUFBzABhh9odHRwOi8vb2NzcC1xYS5o
dWJqZWN0LmNvbTo4MDgwMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAgNJADBG
AiEAsApDKLvPUVuDCtsIAnn/+prsGu5aekwd59tLiCHAFwACIQCFGJHvTz7JUrq/
QJhQzehduW/+oaROsqOp8L3JdEO6XA==
-----END CERTIFICATE-----

47 changes: 47 additions & 0 deletions e2e-tests/everest/config/certificates/HUBOpenProvCert002.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
-----BEGIN CERTIFICATE-----
MIIB9jCCAZygAwIBAgIQWg+8k4JcqPIZeX5bj3LoBzAKBggqhkjOPQQDAjBDMQsw
CQYDVQQGEwJERTEVMBMGA1UEChMMSHViamVjdCBHbWJIMR0wGwYDVQQDExRNTyBT
dWIyIENBIFFBIEcxLjIuMTAeFw0yMzA1MjMxMjU3MDlaFw0yNDAzMDEwMDAwMDBa
MCsxEDAOBgNVBAoTB0h1YmplY3QxFzAVBgNVBAMTDkVNUDc3VFdUVzAwMDAzMFkw
EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKsUiYDu/OGHjKEq39spSiS6CdE9q4jg6
ysuA3ACCKCH5S9Y8YGqy73Dy+fHUZpdzFOAPoYJEK4srYAwgH221z6OBiTCBhjAP
BgNVHRMBAf8EBTADAQEAMBEGA1UdDgQKBAhJFUMGc8ldDzATBgNVHSMEDDAKgAhF
LmmhNiJsSDA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUHMAGGH2h0dHA6Ly9vY3Nw
LXFhLmh1YmplY3QuY29tOjgwODAwDgYDVR0PAQH/BAQDAgPoMAoGCCqGSM49BAMC
A0gAMEUCIBYBkDz5gexjKLYJsQZua4AktjO6IqYSFXp9bJ2MOE6/AiEA3iAuGdty
i24pSc5F8qCbDQKnNASWWMrFVOOJFVh1n7c=
-----END CERTIFICATE-----
subject=/C=DE/O=Hubject GmbH/CN=MO Sub2 CA QA G1.2.1
issuer=/C=DE/O=Hubject GmbH/CN=MO Sub1 CA QA G1.2
-----BEGIN CERTIFICATE-----
MIICDzCCAbWgAwIBAgIQXd9CzQy8+VxpQt9IwNrOETAKBggqhkjOPQQDAjBBMQsw
CQYDVQQGEwJERTEVMBMGA1UEChMMSHViamVjdCBHbWJIMRswGQYDVQQDExJNTyBT
dWIxIENBIFFBIEcxLjIwHhcNMjIwNDEwMjE1OTU5WhcNMzIwNDEwMjE1OTU5WjBD
MQswCQYDVQQGEwJERTEVMBMGA1UEChMMSHViamVjdCBHbWJIMR0wGwYDVQQDExRN
TyBTdWIyIENBIFFBIEcxLjIuMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGRs
p5TTDIGpB+PEwmeG8D7Pgo/WN3U35Rxhe5ttLLlyF2jlmtOPHeHxWgGb0AO7H3L6
nso0A7Nn2KfDP8tG+OujgYwwgYkwEgYDVR0TAQH/BAgwBgEB/wIBADARBgNVHQ4E
CgQIRS5poTYibEgwEwYDVR0jBAwwCoAISw94EhgPO18wOwYIKwYBBQUHAQEELzAt
MCsGCCsGAQUFBzABhh9odHRwOi8vb2NzcC1xYS5odWJqZWN0LmNvbTo4MDgwMA4G
A1UdDwEB/wQEAwIBxjAKBggqhkjOPQQDAgNIADBFAiBqFxXTwnpm0eEgBPj/Px0k
aEvZWdyZPm7BLJVJM6fT3QIhAKZPDhuau2DcN9xrrRPqqZLjfqPSMWw1D0VlCTqC
uv2k
-----END CERTIFICATE-----

subject=/C=DE/O=Hubject GmbH/CN=MO Sub1 CA QA G1.2
issuer=/C=DE/O=Hubject GmbH/DC=V2G/CN=V2G Root CA QA G1
-----BEGIN CERTIFICATE-----
MIICIjCCAcegAwIBAgIQIOuk+8fAbyXQizBVpSI55zAKBggqhkjOPQQDAjBVMQsw
CQYDVQQGEwJERTEVMBMGA1UEChMMSHViamVjdCBHbWJIMRMwEQYKCZImiZPyLGQB
GRYDVjJHMRowGAYDVQQDExFWMkcgUm9vdCBDQSBRQSBHMTAeFw0yMjA0MDcxNDEz
MDdaFw00MjA0MDcxNDEzMDdaMEExCzAJBgNVBAYTAkRFMRUwEwYDVQQKEwxIdWJq
ZWN0IEdtYkgxGzAZBgNVBAMTEk1PIFN1YjEgQ0EgUUEgRzEuMjBZMBMGByqGSM49
AgEGCCqGSM49AwEHA0IABLWnWSw4NPNInduDQp6H0IFgeY0WtO0F3utqV191XLIe
spoAoSIz7s4Vhf+BhbbeX+UyftbGDp2m9EjGIBhog+mjgYwwgYkwEgYDVR0TAQH/
BAgwBgEB/wIBATARBgNVHQ4ECgQISw94EhgPO18wEwYDVR0jBAwwCoAIS0X/giX8
EJYwOwYIKwYBBQUHAQEELzAtMCsGCCsGAQUFBzABhh9odHRwOi8vb2NzcC1xYS5o
dWJqZWN0LmNvbTo4MDgwMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAgNJADBG
AiEAsApDKLvPUVuDCtsIAnn/+prsGu5aekwd59tLiCHAFwACIQCFGJHvTz7JUrq/
QJhQzehduW/+oaROsqOp8L3JdEO6XA==
-----END CERTIFICATE-----

Loading

0 comments on commit 3936fde

Please sign in to comment.