diff --git a/.github/workflows/autogen.yaml b/.github/workflows/autogen.yaml index c9b60abc..62becf2a 100644 --- a/.github/workflows/autogen.yaml +++ b/.github/workflows/autogen.yaml @@ -6,6 +6,9 @@ on: pull_request: paths-ignore: - '*.md' + - 'example/**' + - 'docs/**' + - 'Makefile' jobs: mockery: @@ -18,34 +21,34 @@ jobs: steps: - name: Checkout (pull request) - uses: actions/checkout@v4 + uses: actions/checkout@v6 if: github.event_name == 'pull_request' with: ref: ${{ github.head_ref }} repository: ${{ github.event.pull_request.head.repo.full_name }} - name: Checkout (default) - uses: actions/checkout@v4 + uses: actions/checkout@v6 if: github.event_name != 'pull_request' with: ref: ${{ github.head_ref }} - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: 1.17 - name: Install Mockery - uses: jaxxstorm/action-install-gh-release@v1.10.0 + uses: jaxxstorm/action-install-gh-release@v2.1.0 with: # Grab a specific tag repo: vektra/mockery - tag: v2.51.0 + tag: v2.53.5 - name: Generate mocks run: mockery # Commit all changed files back to the repository - - uses: stefanzweifel/git-auto-commit-action@v5 + - uses: stefanzweifel/git-auto-commit-action@v7 #with: # commit_message: [ Autogen ] Generated mocks # # Mockery can generate new files, so we need to add them to the commit as well diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml new file mode 100644 index 00000000..a327f845 --- /dev/null +++ b/.github/workflows/bench.yml @@ -0,0 +1,58 @@ +name: Benchmarks +on: + push: + branches: + - main + pull_request: + branches: + - main + paths: + # Only run the benchmark on internals + - 'internal/**' + - 'ocppj/**' + - 'ws/**' + - 'go.mod' + +jobs: + benchmark: + name: Performance regression check + runs-on: ubuntu-latest + permissions: + contents: read + # Needed for posting comments on PRs + pull-requests: write + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-go@v6 + with: + go-version: "stable" + + - name: Run benchmarks + run: make benchmarks + + # Download previous benchmark result from cache (if exists) + - name: Download previous benchmark data + uses: actions/cache@v4 + with: + path: ./cache + key: ${{ runner.os }}-benchmark + # Run `github-action-benchmark` action + - name: Store benchmark result + uses: benchmark-action/github-action-benchmark@v1 + with: + # What benchmark tool the output.txt came from + tool: 'go' + # Where the output from the benchmark tool is stored + output-file-path: benchmarks.txt + # Where the previous data file is stored + external-data-json-path: ./cache/benchmark-data.json + # Workflow will fail when an alert happens + fail-on-alert: false + # GitHub API token to make a commit comment + github-token: ${{ secrets.GITHUB_TOKEN }} + # Always post a comment on the PR with benchmark results + comment-always: 'true' + # Enable alert commit comment + comment-on-alert: true + # Enable Job Summary for PRs + summary-always: true \ No newline at end of file diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml deleted file mode 100644 index 780eeb7c..00000000 --- a/.github/workflows/docker-publish.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Publish examples -on: - push: - paths-ignore: - - "**.md" - branches: - - master -jobs: - publish_latest: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4.2.2 - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - - uses: docker/setup-buildx-action@v3 - - name: Login to DockerHub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - name: Build Central System 1.6 example - uses: docker/build-push-action@v6 - with: - push: true - tags: ldonini/ocpp1.6-central-system:latest - file: example/1.6/cs/Dockerfile - platforms: linux/amd64,linux/arm64 - context: . - - name: Build Charge Point 1.6 example - uses: docker/build-push-action@v6 - with: - push: true - tags: ldonini/ocpp1.6-charge-point:latest - file: example/1.6/cp/Dockerfile - platforms: linux/amd64,linux/arm64 - context: . - - name: Build CSMS 2.0.1 example - uses: docker/build-push-action@v6 - with: - push: true - tags: ldonini/ocpp2.0.1-csms:latest - file: example/2.0.1/csms/Dockerfile - platforms: linux/amd64,linux/arm64 - context: . - - name: Build Charging Station 2.0.1 example - uses: docker/build-push-action@v6 - with: - push: true - tags: ldonini/ocpp2.0.1-charging-station:latest - file: example/2.0.1/chargingstation/Dockerfile - platforms: linux/amd64,linux/arm64 - context: . diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c985da4a..f70162c3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v6 - name: Setup QEMU uses: docker/setup-qemu-action@v3 - uses: docker/setup-buildx-action@v3 diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index cb19cee5..86016ef6 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -11,19 +11,18 @@ on: - LICENSE workflow_dispatch: - jobs: unit: runs-on: ubuntu-latest name: Unit tests steps: - name: Checkout code - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v6 - name: Run tests run: | - docker compose -f docker-compose.test.yaml up unit_test --abort-on-container-exit + make unit-tests - name: Archive code coverage results - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: unit_coverage_${{ github.sha }} path: ./coverage.out @@ -34,23 +33,73 @@ jobs: needs: unit steps: - name: Checkout code - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v6 - name: Download coverage from unit tests - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: name: unit_coverage_${{ github.sha }} - name: Run integration tests run: | - docker compose -f docker-compose.test.yaml up integration_test --abort-on-container-exit + make integration-tests - name: Merge coverage run: | sed '1d;$d' integration_coverage.out >> coverage.out - name: Archive code coverage results - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: coverage_${{ github.sha }} path: ./coverage.out + performance: + name: Performance tests + runs-on: ubuntu-latest + permissions: + pull-requests: write + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v6 + + - name: Run OCPP 1.6 performance tests + id: ocpp16-perf-test + run: | + make perf-tests-ocpp16-ci + echo "SUMMARY_16=$(jq -r '${{ github.workspace }}/results' summary_16.json)" >> "$GITHUB_OUTPUT" + + - name: Run OCPP 2.0.1 performance tests + id: ocpp201-perf-test + run: | + make perf-tests-ocpp201-ci + echo "SUMMARY_201=$(jq -r '${{ github.workspace }}/results' summary_201.json)" >> "$GITHUB_OUTPUT" + + - name: Report performance test results + uses: actions/upload-artifact@v6 + with: + path: ${{ github.workspace }}/results + name: performance_test_results_${{ github.sha }} + retention-days: 14 + + - name: Post summary to PR + continue-on-error: true + uses: thollander/actions-comment-pull-request@v3 + if: github.event_name == 'pull_request' + with: + message: | + ## Performance Test Results + + ### OCPP 1.6 + ```json + ${{steps.ocpp16-perf-test.outputs.SUMMARY_16}} + ``` + + ### OCPP 2.0.1 + ```json + ${{steps.ocpp201-perf-test.outputs.SUMMARY_201}} + ``` + + pr-number: ${{ github.event.pull_request.number }} + comment-tag: execution + publish_coverage: runs-on: ubuntu-latest # Unit and integration tests must be run before publishing coverage @@ -58,9 +107,9 @@ jobs: name: Publish coverage steps: - name: Checkout code - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v6 - name: Download coverage from tests - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: name: coverage_${{ github.sha }} - name: Publish diff --git a/.gitignore b/.gitignore index 238f1b8e..aea5d65a 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,6 @@ certs/ central_system_sim -charge_point_sim \ No newline at end of file +charge_point_sim +example/1.6/results/** +example/2.0.1/results/** \ No newline at end of file diff --git a/LICENSE b/LICENSE.md similarity index 97% rename from LICENSE rename to LICENSE.md index 8b23445f..15e97968 100644 --- a/LICENSE +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 +Copyright (c) 2025 xBlaz3kx Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile index 4c03455b..6f84d198 100644 --- a/Makefile +++ b/Makefile @@ -1,2 +1,65 @@ -test: - docker compose -f docker-compose.test.yaml up toxiproxy integration_test --abort-on-container-exit +# OCPP_VERSION variable for examples and performance tests (default: 1.6) +# Supported versions: 1.6, 2.0.1 +OCPP_VERSION ?= 1.6 + +# Derive directory path and service name from OCPP_VERSION +OCPP_DIR = example/$(OCPP_VERSION) +OCPP_SERVICE = $(if $(filter 1.6,$(OCPP_VERSION)),central-system,csms) + +.PHONY: test example example-observability example-ocpp-201 example-ocpp-16 example-ocpp16-observability perf-tests perf-tests-ci perf-tests-ocpp16 perf-tests-ocpp201 perf-tests-ocpp21 perf-tests-ocpp16-ci perf-tests-ocpp201-ci perf-tests-ocpp21-ci integration-tests unit-tests benchmarks + +integration-tests: + docker compose -f docker-compose.test.yaml up toxiproxy integration_test --abort-on-container-exit --exit-code-from integration_test + +unit-tests: + docker compose -f docker-compose.test.yaml up unit_test --abort-on-container-exit --exit-code-from unit_test + +# Run benchmarks for ocppj, ws, and internal packages +benchmarks: + docker compose -f docker-compose.test.yaml up benchmarks --abort-on-container-exit --exit-code-from benchmarks + +# Generic example target +# Usage: make example OCPP_VERSION=2.0.1 +example: + docker compose -f $(OCPP_DIR)/docker-compose.yml up --build + +# Generic example with observability enabled +# Usage: make example-observability OCPP_VERSION=2.0.1 +example-observability: + METRICS_ENABLED=true docker compose -f $(OCPP_DIR)/docker-compose.yml -f example/docker-compose.observability.yaml up --build + +# Version-specific targets (for backward compatibility) +example-ocpp-201: + $(MAKE) example OCPP_VERSION=2.0.1 + +example-ocpp-16: + $(MAKE) example OCPP_VERSION=1.6 + +example-ocpp16-observability: + $(MAKE) example-observability OCPP_VERSION=1.6 + +# Generic performance tests target +# Usage: make perf-tests OCPP_VERSION=2.0.1 +perf-tests: + docker compose -f $(OCPP_DIR)/docker-compose.yml \ + -f $(OCPP_DIR)/docker-compose.k6.yml \ + -f example/docker-compose.observability.yaml up --build + +# Generic CI performance tests target +# Usage: make perf-tests-ci OCPP_VERSION=2.0.1 +perf-tests-ci: + docker compose -f $(OCPP_DIR)/docker-compose.yml \ + -f $(OCPP_DIR)/docker-compose.k6-ci.yml up $(OCPP_SERVICE) k6 --build --abort-on-container-exit + +# Version-specific targets (for backward compatibility) +perf-tests-ocpp16: + $(MAKE) perf-tests OCPP_VERSION=1.6 + +perf-tests-ocpp201: + $(MAKE) perf-tests OCPP_VERSION=2.0.1 + +perf-tests-ocpp16-ci: + $(MAKE) perf-tests-ci OCPP_VERSION=1.6 + +perf-tests-ocpp201-ci: + $(MAKE) perf-tests-ci OCPP_VERSION=2.0.1 \ No newline at end of file diff --git a/README.md b/README.md index 729ceb43..d5d8f8c9 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # ocpp-go -[![Build Status](https://github.com/lorenzodonini/ocpp-go/actions/workflows/test.yaml/badge.svg)](https://github.com/lorenzodonini/ocpp-go/actions/workflows/test.yaml) -[![GoDoc](https://img.shields.io/badge/godoc-reference-5272B4)](https://godoc.org/github.com/lorenzodonini/ocpp-go) -[![Coverage Status](https://coveralls.io/repos/github/lorenzodonini/ocpp-go/badge.svg?branch=master)](https://coveralls.io/github/lorenzodonini/ocpp-go?branch=master) -[![Go report](https://goreportcard.com/badge/github.com/lorenzodonini/ocpp-go)](https://goreportcard.com/report/github.com/lorenzodonini/ocpp-go) +[![Build Status](https://github.com/xBlaz3kx/ocpp-go/actions/workflows/test.yaml/badge.svg)](https://github.com/xBlaz3kx/ocpp-go/actions/workflows/test.yaml) +[![GoDoc](https://img.shields.io/badge/godoc-reference-5272B4)](https://godoc.org/github.com/xBlaz3kx/ocpp-go) +[![Coverage Status](https://coveralls.io/repos/github/xBlaz3kx/ocpp-go/badge.svg?branch=master)](https://coveralls.io/github/xBlaz3kx/ocpp-go?branch=master) +[![Go report](https://goreportcard.com/badge/github.com/xBlaz3kx/ocpp-go)](https://goreportcard.com/report/github.com/xBlaz3kx/ocpp-go) Open Charge Point Protocol implementation in Go. @@ -12,12 +12,20 @@ The library targets modern charge points and central systems, running OCPP versi Given that SOAP will no longer be supported in future versions of OCPP, only OCPP-J is supported in this library. There are currently no plans of supporting OCPP-S. +> [!NOTE] +> This library is not affiliated with the Open Charge Alliance (OCA) in any way. + +> [!NOTE] +> This library is a fork of the original [lorenzodonini/ocpp-go](https://github.com/lorenzodonini/ocpp-go) repository. +> There might be some deviations in the API, as the main goal of this fork is to provide a more actively +> maintained version of the library with additional features and improvements, which may not result in stable releases + ## Installation -Go version 1.13+ is required. +Go version 1.22+ is required. ```sh -go get github.com/lorenzodonini/ocpp-go +go get github.com/xBlaz3kx/ocpp-go@latest ``` You will also need to fetch some dependencies: @@ -39,7 +47,9 @@ but naming changed.** Planned milestones and features: -- [ ] Dedicated package for configuration management +- [ ] OCPP 2.1 support (in progress) +- [ ] OCPP 2.1 variable management +- [ ] OCPP 2.0.1 variable management ### Supported versions @@ -47,16 +57,21 @@ Planned milestones and features: - [x] OCPP 1.6 Security extension (documentation available [here](docs/ocpp1.6-security-extension.md)) - [x] OCPP 2.0.1 (examples working, but will need more real-world testing) (documentation available [here](docs/ocpp-2.0.1.md)) +- [x] Dedicated package for configuration management ### Features -The library offers several advanced features, especially at websocket and ocpp-j level. +The library offers several advanced features, especially at `websocket` and `ocpp-j` level. + +- [x] Automatic message validation +- [x] Verbose logging +- [x] Websocket ping-pong +- [x] Extensive OCPP 1.6 configuration management #### Automatic message validation All incoming and outgoing messages are validated by default, using the [validator](gopkg.in/go-playground/validator) -package. -Constraints are defined on every request/response struct, as per OCPP specs. +package. Constraints are defined on every request/response struct, as per OCPP specs. Validation may be disabled at a package level if needed: @@ -79,8 +94,9 @@ log = logrus.New() log.SetFormatter(&logrus.TextFormatter{FullTimestamp: true}) log.SetLevel(logrus.DebugLevel) // Debug level needed to see all logs // Pass own logger to ws and ocppj packages -ws.SetLogger(log.WithField("logger", "websocket")) -ocppj.SetLogger(log.WithField("logger", "ocppj")) + server := ws.NewServer(ws.WithServerLogger(log.WithField("logger", "websocket"))) + // ... use server + client := ocppj.NewClient("id", wsClient, nil, nil, log.WithField("logger", "ocppj")) ``` The logger you pass needs to conform to the `logging.Logger` interface. @@ -89,12 +105,15 @@ Commonly used logging libraries, such as zap or logrus, adhere to this interface If you are using a logger, that isn't conform, you can simply write an adapter between the `Logger` interface and your own logging system. -#### Websocket ping-pong +### Websockets + +#### Ping and pong messages The websocket package supports configuring ping pong for both endpoints. By default, the client sends a ping every 54 seconds and waits for a pong for 60 seconds, before timing out. The values can be configured as follows: + ```go cfg := ws.NewClientTimeoutConfig() cfg.PingPeriod = 10 * time.Second @@ -102,8 +121,10 @@ cfg.PongWait = 20 * time.Second websocketClient.SetTimeoutConfig(cfg) ``` -By default, the server does not send out any pings and waits for a ping from the client for 60 seconds, before timing out. +By default, the server does not send out any pings and waits for a ping from the client for 60 seconds, before timing +out. To configure the server to send out pings, the `PingPeriod` and `PongWait` must be set to a value greater than 0: + ```go cfg := ws.NewServerTimeoutConfig() cfg.PingPeriod = 10 * time.Second @@ -113,7 +134,32 @@ websocketServer.SetTimeoutConfig(cfg) To disable sending ping messages, set the `PingPeriod` value to `0`. +#### Websocket compression + +You can enable websocket compression on both the client and server side. +To enable compression on the client side, use the following code: + +```go +websocketClient := ws.NewClient( +ws.WithClientCompression(true), +) + +``` + +To enable compression on the server side, use the following code: + +```go +websocketServer := ws.NewServer( +ws.WithCompression(true), +) + +``` + ## Contributing Contributions are welcome! Please refer to the [testing](docs/testing.md) guide for instructions on how to run the -tests. \ No newline at end of file +tests. + +## License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE.md) file for details. diff --git a/docker-compose.test.yaml b/docker-compose.test.yaml index 7c220bbd..066a047d 100644 --- a/docker-compose.test.yaml +++ b/docker-compose.test.yaml @@ -8,7 +8,7 @@ services: # The tests might require permissions to write to coverage out files. # If you encounter issues with permissions, you can try running the container as root. user: root - image: cimg/go:1.22.5 + image: cimg/go:1.25 working_dir: /etc/ocpp-go volumes: - .:/etc/ocpp-go:rw @@ -16,14 +16,41 @@ services: - /bin/bash - -c - | + set -e + set -o pipefail go test -v -covermode=count -coverprofile=coverage.out ./ocppj - go test -v -covermode=count -coverprofile=ocpp16.out -coverpkg=github.com/lorenzodonini/ocpp-go/ocpp1.6/... github.com/lorenzodonini/ocpp-go/ocpp1.6_test - go test -v -covermode=count -coverprofile=ocpp201.out -coverpkg=github.com/lorenzodonini/ocpp-go/ocpp2.0.1/... github.com/lorenzodonini/ocpp-go/ocpp2.0.1_test + go test -v -covermode=count -coverprofile=internal.out github.com/xBlaz3kx/ocpp-go/internal/... + go test -v -covermode=count -coverprofile=ocpp-coverage.out ./ocpp + go test -v -covermode=count -coverprofile=ocpp-coverage.out ./ocpp + go test -v -covermode=count -coverprofile=ocpp16.out -coverpkg=github.com/xBlaz3kx/ocpp-go/ocpp1.6/... github.com/xBlaz3kx/ocpp-go/ocpp1.6/config_manager + go test -v -covermode=count -coverprofile=ocpp201.out -coverpkg=github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/... github.com/xBlaz3kx/ocpp-go/ocpp2.0.1_test + sed '1d;$d' ocpp-coverage.out >> coverage.out + sed '1d;$d' internal.out >> coverage.out sed '1d;$d' ocpp16.out >> coverage.out sed '1d;$d' ocpp201.out >> coverage.out + + benchmarks: + # The tests might require permissions to write to coverage out files. + # If you encounter issues with permissions, you can try running the container as root. + user: root + image: cimg/go:1.25 + working_dir: /etc/ocpp-go + volumes: + - .:/etc/ocpp-go:rw + - ./benchmarks.txt:/etc/ocpp-go/benchmarks.txt:rw + command: + - /bin/bash + - -c + - | + set -e + set -o pipefail + go test -bench=. -benchmem ./ocppj | tee -a benchmarks.txt + go test -bench=. -benchmem ./ws | tee -a benchmarks.txt + go test -bench=. -benchmem github.com/xBlaz3kx/ocpp-go/internal/... | tee -a benchmarks.txt + integration_test: - image: cimg/go:1.22.5 + image: cimg/go:1.25 # The tests might require permissions to write to coverage out files. # If you encounter issues with permissions, you can try running the container as root. user: root @@ -38,6 +65,9 @@ services: command: - /bin/bash - -c - - go test ./ws -v -covermode=count -coverprofile=integration_coverage.out + - | + set -e + set -o pipefail + go test ./ws -v -covermode=count -coverprofile=integration_coverage.out volumes: - .:/etc/ocpp-go:rw \ No newline at end of file diff --git a/docs/observability/observability.md b/docs/observability/observability.md new file mode 100644 index 00000000..ea7eadbd --- /dev/null +++ b/docs/observability/observability.md @@ -0,0 +1,69 @@ +# Observability in ocpp-go + +## Metrics + +The library currently supports only websocket and ocpp-j server metrics, which are exported via OpenTelemetry. +To enable metrics, you need to set the metrics exporter on the server: + +```go +// sets up OTLP metrics exporter +func setupMetrics(address string) error { +grpcOpts := []grpc.DialOption{ +grpc.WithTransportCredentials(insecure.NewCredentials()), +} + +client, err := grpc.NewClient(address, grpcOpts...) + +if err != nil { +return errors.Wrap(err, "failed to create gRPC connection to collector") +} + +ctx := context.Background() + +exporter, err := otlpmetricgrpc.New(ctx, otlpmetricgrpc.WithGRPCConn(client)) +if err != nil { +return errors.Wrap(err, "failed to create otlp metric exporter") +} + +resource, err := resource.New(ctx, +resource.WithAttributes( +semconv.ServiceNameKey.String("centralSystem-demo"), +semconv.ServiceVersionKey.String("example"), +), +resource.WithFromEnv(), +resource.WithContainer(), +resource.WithOS(), +resource.WithOSType(), +resource.WithHost(), +) +if err != nil { +return errors.Wrap(err, "failed to create resource") +} + +meterProvider := metricsdk.NewMeterProvider( +metricsdk.WithReader( +metricsdk.NewPeriodicReader( +exporter, +metricsdk.WithInterval(10*time.Second), +), +), +metricsdk.WithResource(resource), +) + +otel.SetMeterProvider(meterProvider) +return nil +} +``` + +You can check out the [reference implementation](../../example/1.6/cs/central_system_sim.go), and deploy it with: + +```bash +make example-ocpp16-observability +``` + +> Note: Deploying the example requires docker and docker compose to be installed. + +The deployment will start a central system with metrics enabled and a +full [observability stack](https://github.com/grafana/docker-otel-lgtm). + +You can log in to Grafana at http://localhost:3000 with the credentials `admin/admin`. \ No newline at end of file diff --git a/docs/observability/performance-testing.md b/docs/observability/performance-testing.md new file mode 100644 index 00000000..e1bebb42 --- /dev/null +++ b/docs/observability/performance-testing.md @@ -0,0 +1,189 @@ +# OCPP Server performance testing with k6 + +This directory contains comprehensive performance tests for OCPP (Open Charge Point Protocol) implementations using +Grafana k6. + +## Test Scenarios + +### Rapid Connect/Disconnect Test + +- **Connection Lifecycle**: 100-200ms per connection +- **Message Frequency**: Random intervals between 50-150ms +- **Reconnection Pattern**: 3-8 reconnections per virtual user +- **Protocol Compliance**: Full OCPP message structure with proper JSON formatting + +## Prerequisites + +### Required Software + +- **k6**: Performance testing framework + ```bash + # macOS + brew install k6 + + # Ubuntu/Debian + sudo gpg -k + sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69 + echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list + sudo apt-get update + sudo apt-get install k6 + + # Windows + choco install k6 + ``` + +## Quick Start + +### 1. Clone and Navigate + +```bash +cd example/k6 +``` + +### 2. Make Script Executable + +```bash +chmod +x run-performance-tests.sh +``` + +### 3. Run All Tests + +```bash +./run-performance-tests.sh +``` + +### 4. Run Specific Protocol Tests + +```bash +# OCPP 1.6 only +./run-performance-tests.sh --ocpp16-only + +# OCPP 2.0.1 only +./run-performance-tests.sh --ocpp201-only +``` + +### 5. Clean Up Infrastructure + +```bash +./run-performance-tests.sh --cleanup +``` + +## Test Configuration + +### Default Test Stages + +```typescript +stages: [ + {duration: '30s', target: 50}, // Ramp up to 50 VUs + {duration: '1m', target: 50}, // Stay at 50 VUs + {duration: '30s', target: 100}, // Ramp up to 100 VUs + {duration: '2m', target: 100}, // Stay at 100 VUs + {duration: '30s', target: 0}, // Ramp down to 0 VUs +] +``` + +### Performance Thresholds + +- **Connection Time**: 95% < 200ms +- **Disconnection Time**: 95% < 100ms +- **Message Rate**: > 100 messages/second +- **WebSocket Performance**: Optimized for rapid connect/disconnect cycles + +### Test Configurations + +The test runner executes multiple configurations: + +- **Test 1**: 25 VUs for 2 minutes +- **Test 2**: 50 VUs for 3 minutes +- **Test 3**: 100 VUs for 5 minutes + +## Test Execution Details + +### Message Generation + +Each virtual user generates: + +- **Unique IDs**: Per charge point and message +- **Realistic Data**: Random but valid OCPP message content +- **Protocol Compliance**: Proper JSON array format `[type, id, action, payload]` + +### Connection Pattern + +1. **Connect**: Establish WebSocket connection +2. **Boot**: Send BootNotification immediately +3. **Disconnect**: Close connection after 100-200ms +4. **Repeat**: Perform 3-8 connection cycles per VU + +## Results and Analysis + +The test results will be pushed to Prometheus and can be visualized in Grafana dashboards. +If running via Docker, this is handled automatically. + +### Key Metrics + +- **Connection Success Rate**: Percentage of successful WebSocket connections +- **Message Throughput**: Messages per second sent and received +- **Response Times**: Time to receive OCPP responses +- **Error Rates**: Connection failures and message errors +- **Resource Utilization**: CPU, memory, and network usage + +### Performance Analysis + +1. **Load Testing**: Verify system behavior under increasing load +2. **Stress Testing**: Identify breaking points and failure modes +3. **Stability Testing**: Ensure consistent performance over time + +## Customization + +### Modifying Test Parameters + +Edit the test files to adjust: + +- **Connection Intervals**: Change timing between connections +- **Message Types**: Add or remove OCPP message types +- **Load Patterns**: Modify VU counts and test durations +- **Thresholds**: Adjust performance expectations + +### Adding New Message Types + +```typescript +// Example: Add new OCPP message +function createCustomMessage() { + const messageId = randomString(8); + const payload = { + // Your custom payload + }; + + return JSON.stringify([MESSAGE_TYPE.CALL, messageId, 'CustomAction', payload]); +} +``` + +### Environment-Specific Configuration + +- **Server URLs**: Update Websocket endpoints +- **Authentication**: Add security headers if required +- **Network Settings**: Adjust timeouts and retry logic + +### Debug Mode + +Enable detailed logging by modifying the test script: + +```typescript +// Add debug logging +console.log(`Debug: Sending message ${message}`); +console.log(`Debug: Connection state ${socket.readyState}`); +``` + +## Support and Resources + +### Documentation + +- [k6 Documentation](https://k6.io/docs/) +- [OCPP 1.6 Specification](https://www.iso.org/standard/68575.html) +- [OCPP 2.0.1 Specification](https://www.iso.org/standard/78523.html) + +### Issues and Contributions + +- Report bugs and feature requests +- Submit pull requests for improvements +- Share performance test results and insights \ No newline at end of file diff --git a/docs/ocpp-1.6.md b/docs/ocpp-1.6.md index bee1c024..2b2bbac7 100644 --- a/docs/ocpp-1.6.md +++ b/docs/ocpp-1.6.md @@ -7,8 +7,8 @@ profile interfaces, e.g.: ```go import ( -"github.com/lorenzodonini/ocpp-go/ocpp1.6/core" -"github.com/lorenzodonini/ocpp-go/ocpp1.6/types" +"github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" +"github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "time" ) @@ -147,8 +147,8 @@ profile interfaces, e.g.: ```go import ( -"github.com/lorenzodonini/ocpp-go/ocpp1.6/core" -"github.com/lorenzodonini/ocpp-go/ocpp1.6/types" +"github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" +"github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) type ChargePointHandler struct { @@ -303,3 +303,81 @@ Then run the following: ``` docker-compose -f example/1.6/docker-compose.tls.yml up charge-point ``` + +## Configuration management + +The configuration management package allows you to manage the configuration keys defined in the OCPP 1.6 specification. +It will automatically check for the validity of the keys and values, and it allows you to register custom key +validators. It will also trigger callbacks when a key is updated, so you can perform custom logic when a key is changed. + +For comprehensive documentation, see the [OCPP 1.6 Configuration Manager guide](./ocpp1.6-config-manager.md). + +Here's a quick example: + +```go +package main + +import ( + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" + "github.com/samber/lo" + log "github.com/sirupsen/logrus" + configManager "github.com/xBlaz3kx/ocpp-go/ocpp1.6/config_manager" +) + +func main() { + log.SetLevel(log.DebugLevel) + + supportedProfiles := []string{core.ProfileName, smartcharging.ProfileName} + defaultConfig, err := configManager.DefaultConfigurationFromProfiles(supportedProfiles...) + if err != nil { + log.Errorf("Error getting default configuration: %v", err) + return + } + + manager, err := configManager.NewV16ConfigurationManager(*defaultConfig, supportedProfiles...) + if err != nil { + log.Errorf("Error creating manager: %v", err) + return + } + + // Get value + value, err := manager.GetConfigurationValue(configManager.AuthorizeRemoteTxRequests) + if err != nil { + log.Errorf("Error getting configuration value: %v", err) + return + } + + log.Println(*value) + + // Update key + val := "false" + err = manager.UpdateKey(configManager.AuthorizeRemoteTxRequests, &val) + if err != nil { + log.Errorf("Error updating key: %v", err) + return + } + + // Get value + value, err = manager.GetConfigurationValue(configManager.AuthorizeRemoteTxRequests) + if err != nil { + log.Errorf("Error getting configuration value: %v", err) + return + } + + log.Println(*value) + + // Register custom key validator, which will prevent the key from being updated + manager.RegisterCustomKeyValidator(func(key configManager.Key, value *string) bool { + return key != configManager.AuthorizeRemoteTxRequests + }) + + // Update key + val = "true" + err = manager.UpdateKey(configManager.AuthorizeRemoteTxRequests, lo.ToPtr(val)) + if err != nil { + log.Errorf("Error updating key: %v", err) + return + } +} +``` \ No newline at end of file diff --git a/docs/ocpp-2.0.1.md b/docs/ocpp-2.0.1.md index e06478cd..665dd316 100644 --- a/docs/ocpp-2.0.1.md +++ b/docs/ocpp-2.0.1.md @@ -24,7 +24,7 @@ More in-depth documentation for v2.0.1 will follow. To start a CSMS instance, run the following: ```go -import "github.com/lorenzodonini/ocpp-go/ocpp2.0.1" +import "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1" csms := ocpp2.NewCSMS(nil, nil) diff --git a/docs/ocpp1.6-config-manager.md b/docs/ocpp1.6-config-manager.md new file mode 100644 index 00000000..a35ebf05 --- /dev/null +++ b/docs/ocpp1.6-config-manager.md @@ -0,0 +1,431 @@ +# OCPP 1.6 Configuration Manager + +The OCPP 1.6 Configuration Manager provides a robust solution for managing configuration keys defined in the OCPP 1.6 +specification. It handles validation, custom validators, update callbacks, and ensures mandatory keys are present based +on the supported OCPP profiles. + +## Overview + +The configuration manager (`ManagerV16`) is designed to: + +- Validate configuration keys and values according to OCPP 1.6 specifications +- Ensure all mandatory keys for selected profiles are present +- Support custom key validators for application-specific validation rules +- Trigger callbacks when configuration keys are updated +- Provide thread-safe operations for concurrent access +- Support multiple OCPP profiles (Core, LocalAuth, SmartCharging, Firmware, ISO15118, Security) + +## Package Import + +```go +import configManager "github.com/xBlaz3kx/ocpp-go/ocpp1.6/config_manager" +``` + +## Getting Started + +### Creating a Configuration Manager + +To create a new configuration manager, you need to: + +1. Define the supported OCPP profiles +2. Create a default configuration (or use the provided defaults) +3. Initialize the manager with the configuration + +```go +package main + +import ( + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" + configManager "github.com/xBlaz3kx/ocpp-go/ocpp1.6/config_manager" +) + +func main() { + // Define supported profiles + supportedProfiles := []string{core.ProfileName, smartcharging.ProfileName} + + // Create default configuration for the profiles + defaultConfig, err := configManager.DefaultConfigurationFromProfiles(supportedProfiles...) + if err != nil { + // Handle error + return + } + + // Create the manager + manager, err := configManager.NewV16ConfigurationManager(*defaultConfig, supportedProfiles...) + if err != nil { + // Handle error - usually means mandatory keys are missing + return + } + + // Manager is ready to use +} +``` + +### Using Default Configurations + +The package provides helper functions to create default configurations for each profile: + +- `DefaultConfigurationFromProfiles(profiles ...string)` - Creates a default configuration for multiple profiles +- `DefaultCoreConfiguration()` - Returns default Core profile configuration keys +- `DefaultLocalAuthConfiguration()` - Returns default LocalAuth profile configuration keys +- `DefaultSmartChargingConfiguration()` - Returns default SmartCharging profile configuration keys +- `DefaultFirmwareConfiguration()` - Returns default Firmware profile configuration keys +- `NewEmptyConfiguration()` - Creates an empty configuration (useful for custom setups) + +## Core Operations + +### Getting Configuration Values + +Retrieve the value of a specific configuration key: + +```go +value, err := manager.GetConfigurationValue(configManager.HeartbeatInterval) +if err != nil { +// Handle error (e.g., key not found) +return +} +if value != nil { +fmt.Printf("Heartbeat interval: %s\n", *value) +} +``` + +### Updating Configuration Keys + +Update a configuration key value: + +```go +newValue := "120" +err := manager.UpdateKey(configManager.HeartbeatInterval, &newValue) +if err != nil { +// Handle error - could be validation failure, readonly key, etc. +return +} +``` + +To remove a value (set to nil), pass `nil`: + +```go +err := manager.UpdateKey(configManager.SomeOptionalKey, nil) +``` + +### Getting Full Configuration + +Retrieve the complete configuration as OCPP ConfigurationKey array: + +```go +config, err := manager.GetConfiguration() +if err != nil { +// Handle error +return +} + +for _, key := range config { +fmt.Printf("Key: %s, Value: %v, Readonly: %v\n", +key.Key, key.Value, key.Readonly) +} +``` + +### Setting Complete Configuration + +Replace the entire configuration (useful for loading from storage): + +```go +newConfig := configManager.Config{ +Version: 1, +Keys: []core.ConfigurationKey{ +// ... your configuration keys +}, +} + +err := manager.SetConfiguration(newConfig) +if err != nil { +// Handle error - validation will ensure mandatory keys are present +return +} +``` + +## Advanced Features + +### Custom Key Validators + +Register a custom validator function to enforce application-specific validation rules: + +```go +manager.RegisterCustomKeyValidator(func (key configManager.Key, value *string) bool { +// Custom validation logic +// Return true if valid, false otherwise + +if key == configManager.HeartbeatInterval { +if value == nil { +return false // Don't allow nil values for heartbeat interval +} +// Parse and validate the interval value +interval, err := strconv.Atoi(*value) +if err != nil { +return false +} +// Ensure interval is between 60 and 3600 seconds +return interval >= 60 && interval <= 3600 +} + +// Allow other keys to be validated by default rules +return true +}) + +// Now updates will be validated using your custom validator +err := manager.UpdateKey(configManager.HeartbeatInterval, lo.ToPtr("30")) +if err != nil { +// Will fail because 30 < 60 +} +``` + +**Note:** The custom validator is called for ALL keys. If you want to allow default validation for some keys, return +`true` for those keys in your validator function. + +### Update Handlers + +Register handlers to be called automatically when specific keys are updated: + +```go +err := manager.OnUpdateKey(configManager.HeartbeatInterval, func(value *string) error { +if value != nil { +interval, err := strconv.Atoi(*value) +if err != nil { +return err +} +// Apply the new heartbeat interval to your system +fmt.Printf("Updating heartbeat interval to %d seconds\n", interval) +// ... your custom logic here +} +return nil +}) +if err != nil { +// Handle error - key must exist in configuration +return +} + +// When you update the key, the handler will be called automatically +err = manager.UpdateKey(configManager.HeartbeatInterval, lo.ToPtr("120")) +// Handler is called after successful update +``` + +**Important:** Update handlers are called synchronously after the key update succeeds. Keep handler logic fast to avoid +blocking other operations. + +### Mandatory Keys Management + +The manager automatically tracks mandatory keys based on the profiles you specify. You can: + +**Get mandatory keys:** + +```go +mandatoryKeys := manager.GetMandatoryKeys() +for _, key := range mandatoryKeys { +fmt.Println(key.String()) +} +``` + +**Add additional mandatory keys:** + +```go +additionalKeys := []configManager.Key{ +configManager.SomeCustomKey, +} +err := manager.SetMandatoryKeys(additionalKeys) +if err != nil { +// Handle error +return +} +``` + +**Note:** When you set mandatory keys, they are added to the existing list. The manager will ensure all mandatory keys +are present when validating configurations. + +## Supported Configuration Keys + +The package provides constants for all OCPP 1.6 configuration keys: + +### Core Profile Keys + +- `AuthorizeRemoteTxRequests` +- `HeartbeatInterval` +- `ConnectionTimeOut` +- `MeterValueSampleInterval` +- `NumberOfConnectors` +- `SupportedFeatureProfiles` +- And many more... + +### LocalAuth Profile Keys + +- `LocalAuthListEnabled` +- `LocalAuthListMaxLength` +- `SendLocalListMaxLength` + +### SmartCharging Profile Keys + +- `ChargeProfileMaxStackLevel` +- `ChargingScheduleAllowedChargingRateUnit` +- `ChargingScheduleMaxPeriods` +- `MaxChargingProfilesInstalled` + +### Firmware Profile Keys + +- `SupportedFileTransferProtocols` + +### ISO15118 Profile Keys + +- `ISO15118PnCEnabled` +- `ContractValidationOffline` +- `CentralContractValidationAllowed` +- And more... + +### Security Extension Keys + +- `SecurityProfile` +- `CpoName` +- `AuthorizationData` +- And more... + +See `keys.go` for the complete list of available keys. + +## Error Handling + +The manager returns specific errors for different failure scenarios: + +- `ErrKeyCannotBeEmpty` - Attempted to use an empty key +- `ErrKeyNotFound` - Configuration key doesn't exist +- `ErrReadOnly` - Attempted to update a readonly key +- Validation errors - Custom validator rejected the value + +Always check errors when performing operations: + +```go +value, err := manager.GetConfigurationValue(configManager.HeartbeatInterval) +if err != nil { +switch err { +case configManager.ErrKeyNotFound: +// Key doesn't exist in configuration +case configManager.ErrKeyCannotBeEmpty: +// Invalid key provided +default: +// Other error +} +return +} +``` + +## Complete Example + +Here's a complete example demonstrating all major features: + +```go +package main + +import ( + "fmt" + "log" + + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" + "github.com/samber/lo" + configManager "github.com/xBlaz3kx/ocpp-go/ocpp1.6/config_manager" +) + +func main() { + // 1. Create default configuration + supportedProfiles := []string{core.ProfileName, smartcharging.ProfileName} + defaultConfig, err := configManager.DefaultConfigurationFromProfiles(supportedProfiles...) + if err != nil { + log.Fatalf("Failed to create default config: %v", err) + } + + // 2. Initialize manager + manager, err := configManager.NewV16ConfigurationManager(*defaultConfig, supportedProfiles...) + if err != nil { + log.Fatalf("Failed to create manager: %v", err) + } + + // 3. Register custom validator + manager.RegisterCustomKeyValidator(func(key configManager.Key, value *string) bool { + // Prevent updating AuthorizeRemoteTxRequests to false + if key == configManager.AuthorizeRemoteTxRequests && value != nil && *value == "false" { + return false + } + return true + }) + + // 4. Register update handler + err = manager.OnUpdateKey(configManager.HeartbeatInterval, func(value *string) error { + if value != nil { + log.Printf("Heartbeat interval updated to: %s", *value) + } + return nil + }) + if err != nil { + log.Printf("Failed to register update handler: %v", err) + } + + // 5. Get current value + value, err := manager.GetConfigurationValue(configManager.HeartbeatInterval) + if err != nil { + log.Fatalf("Failed to get value: %v", err) + } + fmt.Printf("Current heartbeat interval: %s\n", *value) + + // 6. Update value (handler will be called automatically) + newValue := "180" + err = manager.UpdateKey(configManager.HeartbeatInterval, &newValue) + if err != nil { + log.Fatalf("Failed to update: %v", err) + } + + // 7. Verify update + value, _ = manager.GetConfigurationValue(configManager.HeartbeatInterval) + fmt.Printf("Updated heartbeat interval: %s\n", *value) + + // 8. Try to update with invalid value (will fail due to validator) + err = manager.UpdateKey(configManager.AuthorizeRemoteTxRequests, lo.ToPtr("false")) + if err != nil { + fmt.Printf("Update rejected (as expected): %v\n", err) + } + + // 9. Get full configuration + config, err := manager.GetConfiguration() + if err != nil { + log.Fatalf("Failed to get configuration: %v", err) + } + fmt.Printf("Total configuration keys: %d\n", len(config)) + + // 10. Display mandatory keys + mandatoryKeys := manager.GetMandatoryKeys() + fmt.Printf("Mandatory keys count: %d\n", len(mandatoryKeys)) +} +``` + +## Best Practices + +1. **Always validate errors** - The manager returns errors for invalid operations. Always check and handle them + appropriately. + +2. **Use default configurations** - Start with `DefaultConfigurationFromProfiles()` to ensure you have all required keys + with sensible defaults. + +3. **Register validators early** - Set up custom validators before allowing updates to prevent invalid configurations. + +4. **Keep handlers lightweight** - Update handlers are called synchronously. Perform heavy operations asynchronously if + needed. + +5. **Handle nil values** - Configuration values can be `nil` (for optional keys). Always check before dereferencing. + +6. **Use constants for keys** - Always use the provided constants (e.g., `configManager.HeartbeatInterval`) instead of + string literals to avoid typos. + +7. **Profile-specific keys** - Remember that mandatory keys depend on the profiles you support. Ensure your + configuration includes keys for all supported profiles. + +## See Also + +- [OCPP 1.6 Documentation](./ocpp-1.6.md) - General OCPP 1.6 usage guide +- [Package Source Code](../ocpp1.6/config_manager/) - Full implementation details + diff --git a/example/1.6/cp/Dockerfile b/example/1.6/cp/Dockerfile index 1717a347..3327e31e 100644 --- a/example/1.6/cp/Dockerfile +++ b/example/1.6/cp/Dockerfile @@ -1,10 +1,10 @@ ############################ # STEP 1 build executable binary ############################ -FROM golang:alpine AS builder +FROM golang:1.25-alpine AS builder ENV GO111MODULE on -WORKDIR $GOPATH/src/github.com/lorenzodonini/ocpp-go +WORKDIR $GOPATH/src/github.com/xBlaz3kx/ocpp-go COPY . . # Fetch dependencies. RUN go mod download diff --git a/example/1.6/cp/charge_point_sim.go b/example/1.6/cp/charge_point_sim.go index ffad0c1f..5e74fa65 100644 --- a/example/1.6/cp/charge_point_sim.go +++ b/example/1.6/cp/charge_point_sim.go @@ -8,15 +8,13 @@ import ( "strconv" "time" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/logging" "github.com/sirupsen/logrus" - - ocpp16 "github.com/lorenzodonini/ocpp-go/ocpp1.6" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/lorenzodonini/ocpp-go/ocppj" - "github.com/lorenzodonini/ocpp-go/ws" + ocpp16 "github.com/xBlaz3kx/ocpp-go/ocpp1.6" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/logging" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ws" ) const ( @@ -30,11 +28,11 @@ const ( var log *logrus.Logger -func setupChargePoint(chargePointID string) ocpp16.ChargePoint { - return ocpp16.NewChargePoint(chargePointID, nil, nil) +func setupChargePoint(chargePointID string) (ocpp16.ChargePoint, error) { + return ocpp16.NewChargePoint(chargePointID, nil, nil, log.WithField("logger", "ocppj")) } -func setupTlsChargePoint(chargePointID string) ocpp16.ChargePoint { +func setupTlsChargePoint(chargePointID string) (ocpp16.ChargePoint, error) { certPool, err := x509.SystemCertPool() if err != nil { log.Fatal(err) @@ -68,7 +66,8 @@ func setupTlsChargePoint(chargePointID string) ocpp16.ChargePoint { RootCAs: certPool, Certificates: clientCertificates, })) - return ocpp16.NewChargePoint(chargePointID, nil, client) + + return ocpp16.NewChargePoint(chargePointID, nil, client, log) } // exampleRoutine simulates a charge point flow, where @@ -153,13 +152,18 @@ func main() { } // Check if TLS enabled t, _ := os.LookupEnv(envVarTls) + var err error tlsEnabled, _ := strconv.ParseBool(t) // Prepare OCPP 1.6 charge point (chargePoint variable is defined in handler.go) if tlsEnabled { - chargePoint = setupTlsChargePoint(id) + chargePoint, err = setupTlsChargePoint(id) } else { - chargePoint = setupChargePoint(id) + chargePoint, err = setupChargePoint(id) + } + if err != nil { + log.Fatal(err) } + // Setup some basic state management connectors := map[int]*ConnectorInfo{ 1: {status: core.ChargePointStatusAvailable, availability: core.AvailabilityTypeOperative, currentTransaction: 0}, @@ -185,10 +189,8 @@ func main() { chargePoint.SetExtendedTriggerMessageHandler(handler) chargePoint.SetSecurityHandler(handler) - ocppj.SetLogger(log.WithField("logger", "ocppj")) - ws.SetLogger(log.WithField("logger", "websocket")) // Connects to central system - err := chargePoint.Start(csUrl) + err = chargePoint.Start(csUrl) if err != nil { log.Errorln(err) } else { diff --git a/example/1.6/cp/config.go b/example/1.6/cp/config.go index dcf9f978..5a2bc977 100644 --- a/example/1.6/cp/config.go +++ b/example/1.6/cp/config.go @@ -4,13 +4,13 @@ import ( "fmt" "strconv" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/remotetrigger" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/remotetrigger" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) const ( diff --git a/example/1.6/cp/handler.go b/example/1.6/cp/handler.go index ecfe1566..79add141 100644 --- a/example/1.6/cp/handler.go +++ b/example/1.6/cp/handler.go @@ -7,19 +7,19 @@ import ( "os" "time" - ocpp16 "github.com/lorenzodonini/ocpp-go/ocpp1.6" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/certificates" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/extendedtriggermessage" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/logging" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/remotetrigger" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/securefirmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/security" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + ocpp16 "github.com/xBlaz3kx/ocpp-go/ocpp1.6" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/certificates" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/extendedtriggermessage" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/logging" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/remotetrigger" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/securefirmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/security" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // ConnectorInfo contains some simple state about a single connector. diff --git a/example/1.6/cs/Dockerfile b/example/1.6/cs/Dockerfile index 67874ea9..66612b7e 100644 --- a/example/1.6/cs/Dockerfile +++ b/example/1.6/cs/Dockerfile @@ -1,10 +1,10 @@ ############################ # STEP 1 build executable binary ############################ -FROM golang:alpine AS builder +FROM golang:1.25-alpine AS builder ENV GO111MODULE on -WORKDIR $GOPATH/src/github.com/lorenzodonini/ocpp-go +WORKDIR $GOPATH/src/github.com/xBlaz3kx/ocpp-go COPY . . # Fetch dependencies. RUN go mod download diff --git a/example/1.6/cs/central_system_sim.go b/example/1.6/cs/central_system_sim.go index 8eeee105..ac66a2ab 100644 --- a/example/1.6/cs/central_system_sim.go +++ b/example/1.6/cs/central_system_sim.go @@ -1,23 +1,33 @@ package main import ( + "context" "crypto/tls" "crypto/x509" "os" + "os/signal" "strconv" "time" - "github.com/sirupsen/logrus" + "github.com/grafana/pyroscope-go" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" - ocpp16 "github.com/lorenzodonini/ocpp-go/ocpp1.6" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/remotetrigger" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/lorenzodonini/ocpp-go/ocppj" - "github.com/lorenzodonini/ocpp-go/ws" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + ocpp16 "github.com/xBlaz3kx/ocpp-go/ocpp1.6" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/remotetrigger" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ws" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" + metricsdk "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/resource" + semconv "go.opentelemetry.io/otel/semconv/v1.10.0" ) const ( @@ -28,16 +38,20 @@ const ( envVarCaCertificate = "CA_CERTIFICATE_PATH" envVarServerCertificate = "SERVER_CERTIFICATE_PATH" envVarServerCertificateKey = "SERVER_CERTIFICATE_KEY_PATH" + envVarMetricsEnabled = "METRICS_ENABLED" + envVarMetricsAddress = "METRICS_ADDRESS" + envProfilingEnabled = "PROFILING_ENABLED" + envPyroscopeAddress = "PYROSCOPE_ADDRESS" ) var log *logrus.Logger var centralSystem ocpp16.CentralSystem -func setupCentralSystem() ocpp16.CentralSystem { - return ocpp16.NewCentralSystem(nil, nil) +func setupCentralSystem() (ocpp16.CentralSystem, error) { + return ocpp16.NewCentralSystem(nil, nil, log) } -func setupTlsCentralSystem() ocpp16.CentralSystem { +func setupTlsCentralSystem() (ocpp16.CentralSystem, error) { var certPool *x509.CertPool // Load CA certificates caCertificate, ok := os.LookupEnv(envVarCaCertificate) @@ -71,7 +85,7 @@ func setupTlsCentralSystem() ocpp16.CentralSystem { ClientAuth: tls.RequireAndVerifyClientCert, ClientCAs: certPool, })) - return ocpp16.NewCentralSystem(nil, server) + return ocpp16.NewCentralSystem(nil, server, log) } // Run for every connected Charge Point, to simulate some functionality @@ -188,8 +202,56 @@ func exampleRoutine(chargePointID string, handler *CentralSystemHandler) { } } +// sets up OTLP metrics exporter +func setupMetrics(ctx context.Context, address string) error { + grpcOpts := []grpc.DialOption{ + grpc.WithTransportCredentials(insecure.NewCredentials()), + } + + client, err := grpc.NewClient(address, grpcOpts...) + if err != nil { + return errors.Wrap(err, "failed to create gRPC connection to collector") + } + + exporter, err := otlpmetricgrpc.New(ctx, otlpmetricgrpc.WithGRPCConn(client)) + if err != nil { + return errors.Wrap(err, "failed to create otlp metric exporter") + } + + resource, err := resource.New(ctx, + resource.WithAttributes( + semconv.ServiceNameKey.String("centralSystem-demo"), + semconv.ServiceVersionKey.String("example"), + ), + resource.WithFromEnv(), + resource.WithContainer(), + resource.WithOS(), + resource.WithOSType(), + resource.WithHost(), + ) + if err != nil { + return errors.Wrap(err, "failed to create resource") + } + + meterProvider := metricsdk.NewMeterProvider( + metricsdk.WithReader( + metricsdk.NewPeriodicReader( + exporter, + metricsdk.WithInterval(100*time.Millisecond), + ), + ), + metricsdk.WithResource(resource), + ) + + otel.SetMeterProvider(meterProvider) + return nil +} + // Start function func main() { + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill) + defer cancel() + // Load config from ENV var listenPort = defaultListenPort port, _ := os.LookupEnv(envVarServerPort) @@ -198,15 +260,61 @@ func main() { } else { log.Printf("no valid %v environment variable found, using default port", envVarServerPort) } + + // Setup metrics if enabled + if t, _ := os.LookupEnv(envVarMetricsEnabled); t == "true" { + address, _ := os.LookupEnv(envVarMetricsAddress) + if err := setupMetrics(ctx, address); err != nil { + log.Error(err) + return + } + } + + if t, _ := os.LookupEnv(envProfilingEnabled); t == "true" { + address, _ := os.LookupEnv(envPyroscopeAddress) + profiler, err := pyroscope.Start(pyroscope.Config{ + ApplicationName: "ocpp16.central_system_sim", + ServerAddress: address, + ProfileTypes: []pyroscope.ProfileType{ + pyroscope.ProfileCPU, + pyroscope.ProfileInuseObjects, + pyroscope.ProfileAllocObjects, + pyroscope.ProfileInuseSpace, + pyroscope.ProfileAllocSpace, + pyroscope.ProfileGoroutines, + pyroscope.ProfileMutexCount, + pyroscope.ProfileMutexDuration, + pyroscope.ProfileBlockCount, + pyroscope.ProfileBlockDuration, + }, + }) + if err != nil { + log.Error(err) + return + } + + defer func() { + profiler.Flush(true) + _ = profiler.Stop() + }() + } + // Check if TLS enabled t, _ := os.LookupEnv(envVarTls) tlsEnabled, _ := strconv.ParseBool(t) + + var err error // Prepare OCPP 1.6 central system if tlsEnabled { - centralSystem = setupTlsCentralSystem() + centralSystem, err = setupTlsCentralSystem() } else { - centralSystem = setupCentralSystem() + centralSystem, err = setupCentralSystem() } + + if err != nil { + log.Fatalf("couldn't create central system: %v", err) + } + // Support callbacks for all OCPP 1.6 profiles handler := &CentralSystemHandler{chargePoints: map[string]*ChargePointState{}} centralSystem.SetCoreHandler(handler) @@ -223,19 +331,30 @@ func main() { // Add handlers for dis/connection of charge points centralSystem.SetNewChargePointHandler(func(chargePoint ocpp16.ChargePointConnection) { + // State should be thread-safe + handler.mu.Lock() handler.chargePoints[chargePoint.ID()] = &ChargePointState{connectors: map[int]*ConnectorInfo{}, transactions: map[int]*TransactionInfo{}} + handler.mu.Unlock() + log.WithField("client", chargePoint.ID()).Info("new charge point connected") go exampleRoutine(chargePoint.ID(), handler) }) + centralSystem.SetChargePointDisconnectedHandler(func(chargePoint ocpp16.ChargePointConnection) { log.WithField("client", chargePoint.ID()).Info("charge point disconnected") + + handler.mu.Lock() + defer handler.mu.Unlock() delete(handler.chargePoints, chargePoint.ID()) }) - ocppj.SetLogger(log.WithField("logger", "ocppj")) - ws.SetLogger(log.WithField("logger", "websocket")) - // Run central system + + // Run central system in background log.Infof("starting central system on port %v", listenPort) - centralSystem.Start(listenPort, "/{ws}") + go centralSystem.Start(listenPort, "/{ws}") + + <-ctx.Done() + log.Info("stopping central system") + centralSystem.Stop() log.Info("stopped central system") } diff --git a/example/1.6/cs/handler.go b/example/1.6/cs/handler.go index f10a3546..4bd13c75 100644 --- a/example/1.6/cs/handler.go +++ b/example/1.6/cs/handler.go @@ -2,16 +2,17 @@ package main import ( "fmt" + "sync" "time" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/logging" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/securefirmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/security" "github.com/sirupsen/logrus" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/logging" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/securefirmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/security" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) var ( @@ -45,6 +46,7 @@ func (ci *ConnectorInfo) hasTransactionInProgress() bool { // ChargePointState contains some simple state for a connected charge point type ChargePointState struct { + mu sync.RWMutex status core.ChargePointStatus diagnosticsStatus firmware.DiagnosticsStatus firmwareStatus firmware.FirmwareStatus @@ -65,6 +67,7 @@ func (cps *ChargePointState) getConnector(id int) *ConnectorInfo { // CentralSystemHandler contains some simple state that a central system may want to keep. // In production this will typically be replaced by database/API calls. type CentralSystemHandler struct { + mu sync.RWMutex chargePoints map[string]*ChargePointState } @@ -99,10 +102,14 @@ func (handler *CentralSystemHandler) OnMeterValues(chargePointId string, request } func (handler *CentralSystemHandler) OnStatusNotification(chargePointId string, request *core.StatusNotificationRequest) (confirmation *core.StatusNotificationConfirmation, err error) { + handler.mu.RLock() info, ok := handler.chargePoints[chargePointId] if !ok { + handler.mu.RUnlock() return nil, fmt.Errorf("unknown charge point %v", chargePointId) } + handler.mu.RUnlock() + info.errorCode = request.ErrorCode if request.ConnectorId > 0 { connectorInfo := info.getConnector(request.ConnectorId) @@ -116,14 +123,22 @@ func (handler *CentralSystemHandler) OnStatusNotification(chargePointId string, } func (handler *CentralSystemHandler) OnStartTransaction(chargePointId string, request *core.StartTransactionRequest) (confirmation *core.StartTransactionConfirmation, err error) { + handler.mu.RLock() info, ok := handler.chargePoints[chargePointId] if !ok { + handler.mu.RUnlock() return nil, fmt.Errorf("unknown charge point %v", chargePointId) } + handler.mu.RUnlock() + + // Lock the connector state until the transaction is created + info.mu.Lock() connector := info.getConnector(request.ConnectorId) if connector.currentTransaction >= 0 { + info.mu.Unlock() return nil, fmt.Errorf("connector %v is currently busy with another transaction", request.ConnectorId) } + transaction := &TransactionInfo{} transaction.idTag = request.IdTag transaction.connectorId = request.ConnectorId @@ -133,16 +148,23 @@ func (handler *CentralSystemHandler) OnStartTransaction(chargePointId string, re nextTransactionId += 1 connector.currentTransaction = transaction.id info.transactions[transaction.id] = transaction + info.mu.Unlock() + // TODO: check billable clients logDefault(chargePointId, request.GetFeatureName()).Infof("started transaction %v for connector %v", transaction.id, transaction.connectorId) return core.NewStartTransactionConfirmation(types.NewIdTagInfo(types.AuthorizationStatusAccepted), transaction.id), nil } func (handler *CentralSystemHandler) OnStopTransaction(chargePointId string, request *core.StopTransactionRequest) (confirmation *core.StopTransactionConfirmation, err error) { + handler.mu.RLock() info, ok := handler.chargePoints[chargePointId] if !ok { + handler.mu.RUnlock() return nil, fmt.Errorf("unknown charge point %v", chargePointId) } + handler.mu.RUnlock() + + info.mu.Lock() transaction, ok := info.transactions[request.TransactionId] if ok { connector := info.getConnector(transaction.connectorId) @@ -151,6 +173,8 @@ func (handler *CentralSystemHandler) OnStopTransaction(chargePointId string, req transaction.endMeter = request.MeterStop // TODO: bill charging period to client } + info.mu.Unlock() + logDefault(chargePointId, request.GetFeatureName()).Infof("stopped transaction %v - %v", request.TransactionId, request.Reason) for _, mv := range request.TransactionData { logDefault(chargePointId, request.GetFeatureName()).Printf("%v", mv) @@ -161,20 +185,27 @@ func (handler *CentralSystemHandler) OnStopTransaction(chargePointId string, req // ------------- Firmware management profile callbacks ------------- func (handler *CentralSystemHandler) OnDiagnosticsStatusNotification(chargePointId string, request *firmware.DiagnosticsStatusNotificationRequest) (confirmation *firmware.DiagnosticsStatusNotificationConfirmation, err error) { + handler.mu.RLock() info, ok := handler.chargePoints[chargePointId] if !ok { + handler.mu.RUnlock() return nil, fmt.Errorf("unknown charge point %v", chargePointId) } + handler.mu.RUnlock() + info.diagnosticsStatus = request.Status logDefault(chargePointId, request.GetFeatureName()).Infof("updated diagnostics status to %v", request.Status) return firmware.NewDiagnosticsStatusNotificationConfirmation(), nil } func (handler *CentralSystemHandler) OnFirmwareStatusNotification(chargePointId string, request *firmware.FirmwareStatusNotificationRequest) (confirmation *firmware.FirmwareStatusNotificationConfirmation, err error) { + handler.mu.RLock() info, ok := handler.chargePoints[chargePointId] if !ok { + handler.mu.RUnlock() return nil, fmt.Errorf("unknown charge point %v", chargePointId) } + handler.mu.RUnlock() info.firmwareStatus = request.Status logDefault(chargePointId, request.GetFeatureName()).Infof("updated firmware status to %v", request.Status) return &firmware.FirmwareStatusNotificationConfirmation{}, nil diff --git a/example/1.6/docker-compose.k6-ci.yml b/example/1.6/docker-compose.k6-ci.yml new file mode 100644 index 00000000..b07b33a8 --- /dev/null +++ b/example/1.6/docker-compose.k6-ci.yml @@ -0,0 +1,19 @@ +version: '3.9' +services: + # Requires the central system to be running + k6: + image: grafana/k6:latest + # Run the performance tests + user: ${UID}:${GID} + command: run /scripts/rapid-connect-disconnect.ts --vus 10 --duration 30s --out json=ocpp_16.json --summary-export=summary_16.json + depends_on: + - central-system + networks: + - sim + volumes: + - ./k6:/scripts + - ./results:/home/k6 + +networks: + sim: + driver: bridge diff --git a/example/1.6/docker-compose.k6.yml b/example/1.6/docker-compose.k6.yml new file mode 100644 index 00000000..0b49a2f3 --- /dev/null +++ b/example/1.6/docker-compose.k6.yml @@ -0,0 +1,34 @@ +version: '3.9' +services: + central-system: + depends_on: + - grafana-lgtm-stack + # Setup the central system with metrics and profiling enabled for observability + environment: + - METRICS_ENABLED=${METRICS_ENABLED:-true} + - METRICS_ADDRESS=${METRICS_ADDRESS:-lgtm-stack:4317} + - PROFILING_ENABLED=${PROFILING_ENABLED:-true} + - PYROSCOPE_ADDRESS=${PYROSCOPE_ADDRESS:-http://lgtm-stack:4040} + + k6: + image: grafana/k6:latest + container_name: k6 + # Run the performance tests + command: run -o experimental-prometheus-rw /scripts/rapid-connect-disconnect.ts --vus 10 --duration 1m + depends_on: + - central-system + - grafana-lgtm-stack + networks: + - sim + environment: + # Performance metrics will be pushed to Prometheus via the LGTM stack + - K6_OUTPUTS=prometheus-remote + - K6_PROMETHEUS_RW_SERVER_URL=http://lgtm-stack:9090/api/v1/write + - K6_PROMETHEUS_RW_PUSH_INTERVAL=10s + - K6_PROMETHEUS_RW_TREND_STATS=p(90),p(95),max + volumes: + - ./k6:/scripts + +networks: + sim: + driver: bridge diff --git a/example/1.6/docker-compose.tls.yml b/example/1.6/docker-compose.tls.yml index b4ed7f4e..ba7bbc4f 100644 --- a/example/1.6/docker-compose.tls.yml +++ b/example/1.6/docker-compose.tls.yml @@ -1,4 +1,4 @@ -version: '3' +version: '3.9' services: central-system: build: @@ -15,6 +15,8 @@ services: - CA_CERTIFICATE_PATH=/usr/local/share/certs/ca.crt - SERVER_CERTIFICATE_PATH=/usr/local/share/certs/central-system.crt - SERVER_CERTIFICATE_KEY_PATH=/usr/local/share/certs/central-system.key + - METRICS_ENABLED=${METRICS_ENABLED:-false} + - METRICS_ADDRESS=${METRICS_ADDRESS:-lgtm-stack:4317} ports: - "443:443" networks: diff --git a/example/1.6/docker-compose.yml b/example/1.6/docker-compose.yml index 292aa378..ce5623a7 100644 --- a/example/1.6/docker-compose.yml +++ b/example/1.6/docker-compose.yml @@ -1,25 +1,27 @@ -version: '3' +version: '3.9' services: central-system: build: context: ../.. - dockerfile: cs/Dockerfile + dockerfile: example/1.6/cs/Dockerfile image: ldonini/ocpp1.6-central-system:latest container_name: central-system environment: + - METRICS_ENABLED=${METRICS_ENABLED:-false} + - METRICS_ADDRESS=${METRICS_ADDRESS:-lgtm-stack:4317} - SERVER_LISTEN_PORT=8887 ports: - "8887:8887" networks: - sim - tty: true + # tty: true charge-point: depends_on: central-system: condition: service_started build: context: ../.. - dockerfile: cp/Dockerfile + dockerfile: example/1.6/cp/Dockerfile image: ldonini/ocpp1.6-charge-point:latest container_name: charge-point environment: @@ -27,7 +29,7 @@ services: - CENTRAL_SYSTEM_URL=ws://central-system:8887 networks: - sim - tty: true + # tty: true networks: sim: diff --git a/example/1.6/k6/rapid-connect-disconnect.ts b/example/1.6/k6/rapid-connect-disconnect.ts new file mode 100644 index 00000000..f0be5883 --- /dev/null +++ b/example/1.6/k6/rapid-connect-disconnect.ts @@ -0,0 +1,519 @@ +import {randomIntBetween, randomString} from 'https://jslib.k6.io/k6-utils/1.2.0/index.js'; +import ws from 'k6/ws'; +import {sleep, check} from 'k6'; + +// OCPP 1.6 Core profile message structure constants +const MESSAGE_TYPE = { + CALL: 2, + CALL_RESULT: 3, + CALL_ERROR: 4 +}; + +const ACTIONS = { + BOOT_NOTIFICATION: 'BootNotification', + HEARTBEAT: 'Heartbeat', + STATUS_NOTIFICATION: 'StatusNotification', + AUTHORIZE: 'Authorize', + START_TRANSACTION: 'StartTransaction', + STOP_TRANSACTION: 'StopTransaction', + METER_VALUES: 'MeterValues', + FIRMWARE_STATUS_NOTIFICATION: 'FirmwareStatusNotification', + DIAGNOSTICS_STATUS_NOTIFICATION: 'DiagnosticsStatusNotification', + DATA_TRANSFER: 'DataTransfer' +}; + +// Core profile incoming request actions from central system +const INCOMING_ACTIONS = { + CHANGE_AVAILABILITY: 'ChangeAvailability', + CHANGE_CONFIGURATION: 'ChangeConfiguration', + CLEAR_CACHE: 'ClearCache', + DATA_TRANSFER: 'DataTransfer', + GET_CONFIGURATION: 'GetConfiguration', + REMOTE_START_TRANSACTION: 'RemoteStartTransaction', + REMOTE_STOP_TRANSACTION: 'RemoteStopTransaction', + RESET: 'Reset', + UNLOCK_CONNECTOR: 'UnlockConnector', + GET_DIAGNOSTICS: 'GetDiagnostics', + UPDATE_FIRMWARE: 'UpdateFirmware', + GET_LOCAL_LIST_VERSION: 'GetLocalListVersion', + SEND_LOCAL_LIST: 'SendLocalList', + RESERVE_NOW: 'ReserveNow', + CANCEL_RESERVATION: 'CancelReservation', + SET_CHARGING_PROFILE: 'SetChargingProfile', + CLEAR_CHARGING_PROFILE: 'ClearChargingProfile', + GET_COMPOSITE_SCHEDULE: 'GetCompositeSchedule', + TRIGGER_MESSAGE: 'TriggerMessage' +}; + +// Generate unique charge point ID +function generateChargePointId() { + return `CP_${__VU}_${randomString(8)}`; +} + +// Generate OCPP 1.6 Core profile BootNotification message +function createBootNotification(chargePointId: string) { + const messageId = randomString(8); + const payload = { + chargePointModel: `Model_${randomString(5)}`, + chargePointVendor: `Vendor_${randomString(5)}`, + chargePointSerialNumber: chargePointId, + firmwareVersion: `v${randomIntBetween(1, 9)}.${randomIntBetween(0, 9)}.${randomIntBetween(0, 9)}`, + iccid: randomString(20), + imsi: randomString(15) + }; + + return JSON.stringify([MESSAGE_TYPE.CALL, messageId, ACTIONS.BOOT_NOTIFICATION, payload]); +} + +// Generate OCPP 1.6 Core profile Heartbeat message +function createHeartbeat() { + const messageId = randomString(8); + return JSON.stringify([MESSAGE_TYPE.CALL, messageId, ACTIONS.HEARTBEAT, {}]); +} + +// Generate OCPP 1.6 Core profile StatusNotification message +function createStatusNotification(chargePointId: string, connectorId: number, status: string) { + const messageId = randomString(8); + const payload = { + connectorId: connectorId, + errorCode: 'NoError', + status: status, + timestamp: new Date().toISOString() + }; + + return JSON.stringify([MESSAGE_TYPE.CALL, messageId, ACTIONS.STATUS_NOTIFICATION, payload]); +} + +// Generate OCPP 1.6 Core profile Authorize message +function createAuthorize(idTag: string) { + const messageId = randomString(8); + const payload = { + idTag: idTag + }; + + return JSON.stringify([MESSAGE_TYPE.CALL, messageId, ACTIONS.AUTHORIZE, payload]); +} + +// Generate OCPP 1.6 Core profile StartTransaction message +function createStartTransaction(connectorId: number, idTag: string) { + const messageId = randomString(8); + const payload = { + connectorId: connectorId, + idTag: idTag, + meterStart: randomIntBetween(0, 1000), + timestamp: new Date().toISOString() + }; + + return JSON.stringify([MESSAGE_TYPE.CALL, messageId, ACTIONS.START_TRANSACTION, payload]); +} + +// Generate OCPP 1.6 Core profile StopTransaction message +function createStopTransaction(transactionId: number, meterStop: number) { + const messageId = randomString(8); + const payload = { + transactionId: transactionId, + meterStop: meterStop, + timestamp: new Date().toISOString(), + reason: 'Remote' + }; + + return JSON.stringify([MESSAGE_TYPE.CALL, messageId, ACTIONS.STOP_TRANSACTION, payload]); +} + +// Generate OCPP 1.6 Core profile MeterValues message +function createMeterValues(connectorId: number, transactionId?: number) { + const messageId = randomString(8); + const payload = { + connectorId: connectorId, + transactionId: transactionId, + meterValue: [{ + timestamp: new Date().toISOString(), + sampledValue: [{ + value: randomIntBetween(0, 100000).toString(), + context: 'Sample.Periodic', + measurand: 'Energy.Active.Import.Register', + unit: 'Wh' + }] + }] + }; + + return JSON.stringify([MESSAGE_TYPE.CALL, messageId, ACTIONS.METER_VALUES, payload]); +} + +// Generate OCPP 1.6 Core profile CallResult response +function createCallResult(messageId: string, payload: any) { + return JSON.stringify([MESSAGE_TYPE.CALL_RESULT, messageId, payload]); +} + +// Generate OCPP 1.6 Core profile CallError response +function createCallError(messageId: string, errorCode: string, errorDescription: string) { + return JSON.stringify([MESSAGE_TYPE.CALL_ERROR, messageId, errorCode, errorDescription, {}]); +} + +// Generate OCPP 1.6 Core profile FirmwareStatusNotification message +function createFirmwareStatusNotification(status: string) { + const messageId = randomString(8); + const payload = { + status: status + }; + + return JSON.stringify([MESSAGE_TYPE.CALL, messageId, ACTIONS.FIRMWARE_STATUS_NOTIFICATION, payload]); +} + +// Generate OCPP 1.6 Core profile DiagnosticsStatusNotification message +function createDiagnosticsStatusNotification(status: string) { + const messageId = randomString(8); + const payload = { + status: status + }; + + return JSON.stringify([MESSAGE_TYPE.CALL, messageId, ACTIONS.DIAGNOSTICS_STATUS_NOTIFICATION, payload]); +} + +// Generate OCPP 1.6 Core profile DataTransfer message (outgoing) +function createDataTransfer(vendorId: string, messageId?: string, data?: string) { + const msgId = randomString(8); + const payload = { + vendorId: vendorId, + messageId: messageId, + data: data + }; + + return JSON.stringify([MESSAGE_TYPE.CALL, msgId, ACTIONS.DATA_TRANSFER, payload]); +} + +// Handle incoming Core profile ChangeAvailability request +function handleChangeAvailability(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile ChangeConfiguration request +function handleChangeConfiguration(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile ClearCache request +function handleClearCache(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile DataTransfer request +function handleDataTransfer(request: any) { + return { + status: 'Accepted', + data: `Response to ${request.vendorId}:${request.messageId || 'default'}` + }; +} + +// Handle incoming Core profile GetConfiguration request +function handleGetConfiguration(request: any) { + return { + configurationKey: [ + { + key: 'HeartbeatInterval', + readonly: false, + value: '60' + }, + { + key: 'ConnectionTimeOut', + readonly: false, + value: '60' + } + ], + unknownKey: [] + }; +} + +// Handle incoming Core profile RemoteStartTransaction request +function handleRemoteStartTransaction(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile RemoteStopTransaction request +function handleRemoteStopTransaction(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile Reset request +function handleReset(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile UnlockConnector request +function handleUnlockConnector(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile GetDiagnostics request +function handleGetDiagnostics(request: any) { + return { + fileName: `diagnostics_${Date.now()}.zip` + }; +} + +// Handle incoming Core profile UpdateFirmware request +function handleUpdateFirmware(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile GetLocalListVersion request +function handleGetLocalListVersion(request: any) { + return { + listVersion: randomIntBetween(1, 100) + }; +} + +// Handle incoming Core profile SendLocalList request +function handleSendLocalList(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile ReserveNow request +function handleReserveNow(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile CancelReservation request +function handleCancelReservation(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile SetChargingProfile request +function handleSetChargingProfile(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile ClearChargingProfile request +function handleClearChargingProfile(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile GetCompositeSchedule request +function handleGetCompositeSchedule(request: any) { + return { + status: 'Accepted', + connectorId: request.connectorId, + scheduleStart: new Date(Date.now() + 60000).toISOString(), + chargingSchedule: { + duration: 3600, + startSchedule: new Date().toISOString(), + chargingRateUnit: 'A', + chargingSchedulePeriod: [ + { + startPeriod: 0, + limit: 32 + } + ] + } + }; +} + +// Handle incoming Core profile TriggerMessage request +function handleTriggerMessage(request: any) { + return { + status: 'Accepted' + }; +} + +// Route incoming Core profile requests to appropriate handlers +function handleIncomingRequest(action: string, payload: any, messageId: string) { + let response; + + try { + switch (action) { + case INCOMING_ACTIONS.CHANGE_AVAILABILITY: + response = handleChangeAvailability(payload); + break; + case INCOMING_ACTIONS.CHANGE_CONFIGURATION: + response = handleChangeConfiguration(payload); + break; + case INCOMING_ACTIONS.CLEAR_CACHE: + response = handleClearCache(payload); + break; + case INCOMING_ACTIONS.DATA_TRANSFER: + response = handleDataTransfer(payload); + break; + case INCOMING_ACTIONS.GET_CONFIGURATION: + response = handleGetConfiguration(payload); + break; + case INCOMING_ACTIONS.REMOTE_START_TRANSACTION: + response = handleRemoteStartTransaction(payload); + break; + case INCOMING_ACTIONS.REMOTE_STOP_TRANSACTION: + response = handleRemoteStopTransaction(payload); + break; + case INCOMING_ACTIONS.RESET: + response = handleReset(payload); + break; + case INCOMING_ACTIONS.UNLOCK_CONNECTOR: + response = handleUnlockConnector(payload); + break; + case INCOMING_ACTIONS.GET_DIAGNOSTICS: + response = handleGetDiagnostics(payload); + break; + case INCOMING_ACTIONS.UPDATE_FIRMWARE: + response = handleUpdateFirmware(payload); + break; + case INCOMING_ACTIONS.GET_LOCAL_LIST_VERSION: + response = handleGetLocalListVersion(payload); + break; + case INCOMING_ACTIONS.SEND_LOCAL_LIST: + response = handleSendLocalList(payload); + break; + case INCOMING_ACTIONS.RESERVE_NOW: + response = handleReserveNow(payload); + break; + case INCOMING_ACTIONS.CANCEL_RESERVATION: + response = handleCancelReservation(payload); + break; + case INCOMING_ACTIONS.SET_CHARGING_PROFILE: + response = handleSetChargingProfile(payload); + break; + case INCOMING_ACTIONS.CLEAR_CHARGING_PROFILE: + response = handleClearChargingProfile(payload); + break; + case INCOMING_ACTIONS.GET_COMPOSITE_SCHEDULE: + response = handleGetCompositeSchedule(payload); + break; + case INCOMING_ACTIONS.TRIGGER_MESSAGE: + response = handleTriggerMessage(payload); + break; + default: + console.log(`VU ${__VU}: Unknown incoming action: ${action}`); + return createCallError(messageId, 'NotImplemented', `Action ${action} not implemented`); + } + + return createCallResult(messageId, response); + } catch (error) { + console.log(`VU ${__VU}: Error handling ${action}: ${error}`); + return createCallError(messageId, 'InternalError', `Failed to process ${action}`); + } +} + +export default function () { + const chargePointId = generateChargePointId(); + + // Configurable WebSocket URL from environment variables + const wsHost = __ENV.WS_HOST || 'central-system'; + const wsPort = __ENV.WS_PORT || '8887'; + const wsProtocol = __ENV.WS_PROTOCOL || 'ws'; + const wsPath = __ENV.WS_PATH || ''; + + const url = `${wsProtocol}://${wsHost}:${wsPort}${wsPath}/${chargePointId}`; + + console.log(`VU ${__VU}: Connecting to ${url}`); + + const params = { + // OCPP 1.6 requires specific WebSocket subprotocol + headers: { + 'Sec-WebSocket-Protocol': 'ocpp1.6' + } + }; + + // Track connection metrics + const startTime = Date.now(); + let messageCount = 0; + let reconnectCount = 0; + let maxReconnects = 10; + + while (reconnectCount < maxReconnects) { + const res = ws.connect(url, params, function (socket) { + const connectionStart = Date.now(); + + socket.on('open', function open() { + const connectTime = Date.now() - connectionStart; + console.log(`VU ${__VU}: Connected in ${connectTime}ms (attempt ${reconnectCount + 1}/${maxReconnects})`); + + // Send BootNotification immediately after connection + const bootMsg = createBootNotification(chargePointId); + socket.send(bootMsg); + messageCount++; + + // Disconnect after random time (100-200ms) + const disconnectDelay = randomIntBetween(100, 200); + + socket.setInterval(function timeout() { + socket.ping(); + console.log('Pinging'); + }, disconnectDelay - 10); + + socket.setTimeout(function () { + console.log(`${disconnectDelay} ms passed, closing the socket`); + socket.close(); + }, disconnectDelay); + }); + + socket.on('message', function (message) { + try { + const data = JSON.parse(message); + + if (data[0] === MESSAGE_TYPE.CALL_RESULT) { + console.log(`VU ${__VU}: Received response for message ${data[1]}`); + } else if (data[0] === MESSAGE_TYPE.CALL_ERROR) { + console.log(`VU ${__VU}: Received error for message ${data[1]}: ${data[2]}`); + } else if (data[0] === MESSAGE_TYPE.CALL) { + // Handle incoming request from central system + const messageId = data[1]; + const action = data[2]; + const payload = data[3] || {}; + + console.log(`VU ${__VU}: Received incoming request: ${action} (ID: ${messageId})`); + + // Generate and send response + const response = handleIncomingRequest(action, payload, messageId); + socket.send(response); + + // Track incoming request handling + messageCount++; + } + } catch (e) { + console.log(`VU ${__VU}: Received non-JSON message: ${message}`); + } + }); + + socket.on('close', function () { + const totalTime = Date.now() - connectionStart; + console.log(`VU ${__VU}: Disconnected after ${totalTime}ms`); + reconnectCount++; + }); + + socket.on('error', function (error) { + console.log(`VU ${__VU}: Websocket error: ${error}`); + }); + }); + + check(res, {'status is 101': (r) => r && r.status === 101}); + + // Small delay between reconnections to avoid overwhelming the server + sleep(randomIntBetween(50, 100) / 1000); + } + + // Final metrics + console.log(`VU ${__VU}: Completed ${reconnectCount} connections with ${messageCount} messages in ${Date.now() - startTime}ms`); +} diff --git a/example/2.0.1/chargingstation/Dockerfile b/example/2.0.1/chargingstation/Dockerfile index 6e5a5e0c..f77b36f8 100644 --- a/example/2.0.1/chargingstation/Dockerfile +++ b/example/2.0.1/chargingstation/Dockerfile @@ -1,10 +1,10 @@ ############################ # STEP 1 build executable binary ############################ -FROM golang:alpine AS builder +FROM golang:1.25-alpine AS builder ENV GO111MODULE on -WORKDIR $GOPATH/src/github.com/lorenzodonini/ocpp-go +WORKDIR $GOPATH/src/github.com/xBlaz3kx/ocpp-go COPY . . # Fetch dependencies. RUN go mod download diff --git a/example/2.0.1/chargingstation/authorization_handler.go b/example/2.0.1/chargingstation/authorization_handler.go index 4cffe06a..a4098d7e 100644 --- a/example/2.0.1/chargingstation/authorization_handler.go +++ b/example/2.0.1/chargingstation/authorization_handler.go @@ -1,7 +1,7 @@ package main import ( - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/authorization" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/authorization" ) func (handler *ChargingStationHandler) OnClearCache(request *authorization.ClearCacheRequest) (response *authorization.ClearCacheResponse, err error) { diff --git a/example/2.0.1/chargingstation/availability_handler.go b/example/2.0.1/chargingstation/availability_handler.go index 0748d398..8cfbaee3 100644 --- a/example/2.0.1/chargingstation/availability_handler.go +++ b/example/2.0.1/chargingstation/availability_handler.go @@ -1,7 +1,7 @@ package main import ( - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/availability" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/availability" ) func (handler *ChargingStationHandler) OnChangeAvailability(request *availability.ChangeAvailabilityRequest) (response *availability.ChangeAvailabilityResponse, err error) { diff --git a/example/2.0.1/chargingstation/charging_station_sim.go b/example/2.0.1/chargingstation/charging_station_sim.go index 091723ea..787548a6 100644 --- a/example/2.0.1/chargingstation/charging_station_sim.go +++ b/example/2.0.1/chargingstation/charging_station_sim.go @@ -7,18 +7,17 @@ import ( "strconv" "time" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/availability" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/transactions" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/availability" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/transactions" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "github.com/sirupsen/logrus" - "github.com/lorenzodonini/ocpp-go/ocppj" - "github.com/lorenzodonini/ocpp-go/ws" + "github.com/xBlaz3kx/ocpp-go/ws" ) const ( @@ -32,11 +31,11 @@ const ( var log *logrus.Logger -func setupChargingStation(chargingStationID string) ocpp2.ChargingStation { - return ocpp2.NewChargingStation(chargingStationID, nil, nil) +func setupChargingStation(chargingStationID string) (ocpp2.ChargingStation, error) { + return ocpp2.NewChargingStation(chargingStationID, nil, nil, log) } -func setupTlsChargingStation(chargingStationID string) ocpp2.ChargingStation { +func setupTlsChargingStation(chargingStationID string) (ocpp2.ChargingStation, error) { certPool, err := x509.SystemCertPool() if err != nil { log.Fatal(err) @@ -70,7 +69,7 @@ func setupTlsChargingStation(chargingStationID string) ocpp2.ChargingStation { RootCAs: certPool, Certificates: clientCertificates, })) - return ocpp2.NewChargingStation(chargingStationID, nil, client) + return ocpp2.NewChargingStation(chargingStationID, nil, client, log) } // exampleRoutine simulates a charging station flow, where a dummy transaction is started. @@ -198,12 +197,17 @@ func main() { // Check if TLS enabled t, _ := os.LookupEnv(envVarTls) tlsEnabled, _ := strconv.ParseBool(t) + var err error // Prepare OCPP 2.0.1 charging station (chargingStation variable is defined in handler.go) if tlsEnabled { - chargingStation = setupTlsChargingStation(id) + chargingStation, err = setupTlsChargingStation(id) } else { - chargingStation = setupChargingStation(id) + chargingStation, err = setupChargingStation(id) } + if err != nil { + log.Fatal(err) + } + // Setup some basic state management evse := EVSEInfo{ availability: availability.OperationalStatusOperative, @@ -243,9 +247,9 @@ func main() { chargingStation.SetSmartChargingHandler(handler) chargingStation.SetTariffCostHandler(handler) chargingStation.SetTransactionsHandler(handler) - ocppj.SetLogger(log) + // Connects to central system - err := chargingStation.Start(csmsUrl) + err = chargingStation.Start(csmsUrl) if err != nil { log.Error(err) } else { diff --git a/example/2.0.1/chargingstation/data_handler.go b/example/2.0.1/chargingstation/data_handler.go index feb4551f..9905eec0 100644 --- a/example/2.0.1/chargingstation/data_handler.go +++ b/example/2.0.1/chargingstation/data_handler.go @@ -2,7 +2,7 @@ package main import ( "encoding/json" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/data" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/data" ) type DataSample struct { diff --git a/example/2.0.1/chargingstation/diagnostics_handler.go b/example/2.0.1/chargingstation/diagnostics_handler.go index 2a201120..e365c4c9 100644 --- a/example/2.0.1/chargingstation/diagnostics_handler.go +++ b/example/2.0.1/chargingstation/diagnostics_handler.go @@ -1,8 +1,8 @@ package main import ( - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) func (handler *ChargingStationHandler) OnClearVariableMonitoring(request *diagnostics.ClearVariableMonitoringRequest) (response *diagnostics.ClearVariableMonitoringResponse, err error) { diff --git a/example/2.0.1/chargingstation/display_handler.go b/example/2.0.1/chargingstation/display_handler.go index 21f8bccd..a7718e15 100644 --- a/example/2.0.1/chargingstation/display_handler.go +++ b/example/2.0.1/chargingstation/display_handler.go @@ -1,6 +1,6 @@ package main -import "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/display" +import "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/display" func (handler *ChargingStationHandler) OnClearDisplay(request *display.ClearDisplayRequest) (response *display.ClearDisplayResponse, err error) { logDefault(request.GetFeatureName()).Infof("cleared display message %v", request.ID) diff --git a/example/2.0.1/chargingstation/firmware_handler.go b/example/2.0.1/chargingstation/firmware_handler.go index bd64b32d..cc7dc51c 100644 --- a/example/2.0.1/chargingstation/firmware_handler.go +++ b/example/2.0.1/chargingstation/firmware_handler.go @@ -1,10 +1,10 @@ package main import ( - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" - "github.com/lorenzodonini/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocppj" "io" "net/http" "os" diff --git a/example/2.0.1/chargingstation/handler.go b/example/2.0.1/chargingstation/handler.go index 030b67c2..7309e664 100644 --- a/example/2.0.1/chargingstation/handler.go +++ b/example/2.0.1/chargingstation/handler.go @@ -4,11 +4,11 @@ import ( "fmt" "time" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/availability" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/availability" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // ConnectorInfo contains some simple state about a single connector. diff --git a/example/2.0.1/chargingstation/iso15118_handler.go b/example/2.0.1/chargingstation/iso15118_handler.go index 5987743e..942cbf6e 100644 --- a/example/2.0.1/chargingstation/iso15118_handler.go +++ b/example/2.0.1/chargingstation/iso15118_handler.go @@ -1,9 +1,9 @@ package main import ( - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/iso15118" - "github.com/lorenzodonini/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/iso15118" + "github.com/xBlaz3kx/ocpp-go/ocppj" ) func (handler *ChargingStationHandler) OnDeleteCertificate(request *iso15118.DeleteCertificateRequest) (response *iso15118.DeleteCertificateResponse, err error) { diff --git a/example/2.0.1/chargingstation/localauth_handler.go b/example/2.0.1/chargingstation/localauth_handler.go index ed258f4b..70f472a8 100644 --- a/example/2.0.1/chargingstation/localauth_handler.go +++ b/example/2.0.1/chargingstation/localauth_handler.go @@ -1,6 +1,6 @@ package main -import "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/localauth" +import "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/localauth" func (handler *ChargingStationHandler) OnGetLocalListVersion(request *localauth.GetLocalListVersionRequest) (response *localauth.GetLocalListVersionResponse, err error) { logDefault(request.GetFeatureName()).Infof("returning current local list version: %v", handler.localAuthListVersion) diff --git a/example/2.0.1/chargingstation/provisioning_handler.go b/example/2.0.1/chargingstation/provisioning_handler.go index 9f47b5b7..d6ba83fd 100644 --- a/example/2.0.1/chargingstation/provisioning_handler.go +++ b/example/2.0.1/chargingstation/provisioning_handler.go @@ -1,9 +1,9 @@ package main import ( - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocppj" ) func (handler *ChargingStationHandler) OnGetBaseReport(request *provisioning.GetBaseReportRequest) (response *provisioning.GetBaseReportResponse, err error) { diff --git a/example/2.0.1/chargingstation/remotecontrol_handler.go b/example/2.0.1/chargingstation/remotecontrol_handler.go index 73ed14df..c20d6e0f 100644 --- a/example/2.0.1/chargingstation/remotecontrol_handler.go +++ b/example/2.0.1/chargingstation/remotecontrol_handler.go @@ -4,11 +4,11 @@ import ( "math/rand" "time" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/availability" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/remotecontrol" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/availability" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/remotecontrol" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) func (handler *ChargingStationHandler) OnRequestStartTransaction(request *remotecontrol.RequestStartTransactionRequest) (response *remotecontrol.RequestStartTransactionResponse, err error) { diff --git a/example/2.0.1/chargingstation/reservation_handler.go b/example/2.0.1/chargingstation/reservation_handler.go index 0ad71c50..9299eb24 100644 --- a/example/2.0.1/chargingstation/reservation_handler.go +++ b/example/2.0.1/chargingstation/reservation_handler.go @@ -2,9 +2,9 @@ package main import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/availability" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/availability" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) func (handler *ChargingStationHandler) OnCancelReservation(request *reservation.CancelReservationRequest) (resp *reservation.CancelReservationResponse, err error) { diff --git a/example/2.0.1/chargingstation/smartcharging_handler.go b/example/2.0.1/chargingstation/smartcharging_handler.go index ac702259..fda4b9e3 100644 --- a/example/2.0.1/chargingstation/smartcharging_handler.go +++ b/example/2.0.1/chargingstation/smartcharging_handler.go @@ -1,9 +1,9 @@ package main import ( - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocppj" ) func (handler *ChargingStationHandler) OnClearChargingProfile(request *smartcharging.ClearChargingProfileRequest) (response *smartcharging.ClearChargingProfileResponse, err error) { diff --git a/example/2.0.1/chargingstation/tariffcost_handler.go b/example/2.0.1/chargingstation/tariffcost_handler.go index acfc10e5..ec12da25 100644 --- a/example/2.0.1/chargingstation/tariffcost_handler.go +++ b/example/2.0.1/chargingstation/tariffcost_handler.go @@ -1,7 +1,7 @@ package main import ( - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/tariffcost" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/tariffcost" ) func (handler *ChargingStationHandler) OnCostUpdated(request *tariffcost.CostUpdatedRequest) (response *tariffcost.CostUpdatedResponse, err error) { diff --git a/example/2.0.1/chargingstation/transactions_handler.go b/example/2.0.1/chargingstation/transactions_handler.go index f2975fcd..84c62d96 100644 --- a/example/2.0.1/chargingstation/transactions_handler.go +++ b/example/2.0.1/chargingstation/transactions_handler.go @@ -1,9 +1,9 @@ package main import ( - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/transactions" - "github.com/lorenzodonini/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/transactions" + "github.com/xBlaz3kx/ocpp-go/ocppj" ) func (handler *ChargingStationHandler) OnGetTransactionStatus(request *transactions.GetTransactionStatusRequest) (response *transactions.GetTransactionStatusResponse, err error) { diff --git a/example/2.0.1/csms/Dockerfile b/example/2.0.1/csms/Dockerfile index 07e7a9b4..c0827103 100644 --- a/example/2.0.1/csms/Dockerfile +++ b/example/2.0.1/csms/Dockerfile @@ -1,10 +1,10 @@ ############################ # STEP 1 build executable binary ############################ -FROM golang:alpine AS builder +FROM golang:1.25-alpine AS builder ENV GO111MODULE on -WORKDIR $GOPATH/src/github.com/lorenzodonini/ocpp-go +WORKDIR $GOPATH/src/github.com/xBlaz3kx/ocpp-go COPY . . # Fetch dependencies. RUN go mod download diff --git a/example/2.0.1/csms/authorization_handler.go b/example/2.0.1/csms/authorization_handler.go index 1f93f896..e00434ca 100644 --- a/example/2.0.1/csms/authorization_handler.go +++ b/example/2.0.1/csms/authorization_handler.go @@ -1,8 +1,8 @@ package main import ( - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/authorization" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/authorization" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) func (c *CSMSHandler) OnAuthorize(chargingStationID string, request *authorization.AuthorizeRequest) (response *authorization.AuthorizeResponse, err error) { diff --git a/example/2.0.1/csms/availability_handler.go b/example/2.0.1/csms/availability_handler.go index 962842c0..6b7032d9 100644 --- a/example/2.0.1/csms/availability_handler.go +++ b/example/2.0.1/csms/availability_handler.go @@ -2,9 +2,10 @@ package main import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/availability" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" "time" + + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/availability" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) func (c *CSMSHandler) OnHeartbeat(chargingStationID string, request *availability.HeartbeatRequest) (response *availability.HeartbeatResponse, err error) { @@ -14,10 +15,14 @@ func (c *CSMSHandler) OnHeartbeat(chargingStationID string, request *availabilit } func (c *CSMSHandler) OnStatusNotification(chargingStationID string, request *availability.StatusNotificationRequest) (response *availability.StatusNotificationResponse, err error) { + c.mu.RLock() + defer c.mu.RUnlock() + info, ok := c.chargingStations[chargingStationID] if !ok { return nil, fmt.Errorf("unknown charging station %v", chargingStationID) } + if request.ConnectorID > 0 { connectorInfo := info.getConnector(request.ConnectorID) connectorInfo.status = request.ConnectorStatus diff --git a/example/2.0.1/csms/csms_sim.go b/example/2.0.1/csms/csms_sim.go index 57b88ec9..dbf672bf 100644 --- a/example/2.0.1/csms/csms_sim.go +++ b/example/2.0.1/csms/csms_sim.go @@ -1,26 +1,36 @@ package main import ( + "context" "crypto/tls" "crypto/x509" "fmt" "os" + "os/signal" "strconv" "time" + "github.com/grafana/pyroscope-go" + "github.com/pkg/errors" "github.com/sirupsen/logrus" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" + metricsdk "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/resource" + semconv "go.opentelemetry.io/otel/semconv/v1.10.0" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/availability" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/display" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/remotecontrol" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" - "github.com/lorenzodonini/ocpp-go/ocppj" - "github.com/lorenzodonini/ocpp-go/ws" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/availability" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/display" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/remotecontrol" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ws" ) const ( @@ -31,16 +41,20 @@ const ( envVarCaCertificate = "CA_CERTIFICATE_PATH" envVarServerCertificate = "SERVER_CERTIFICATE_PATH" envVarServerCertificateKey = "SERVER_CERTIFICATE_KEY_PATH" + envVarMetricsEnabled = "METRICS_ENABLED" + envVarMetricsAddress = "METRICS_ADDRESS" + envProfilingEnabled = "PROFILING_ENABLED" + envPyroscopeAddress = "PYROSCOPE_ADDRESS" ) var log *logrus.Logger var csms ocpp2.CSMS -func setupCentralSystem() ocpp2.CSMS { - return ocpp2.NewCSMS(nil, nil) +func setupCentralSystem() (ocpp2.CSMS, error) { + return ocpp2.NewCSMS(nil, nil, log) } -func setupTlsCentralSystem() ocpp2.CSMS { +func setupTlsCentralSystem() (ocpp2.CSMS, error) { var certPool *x509.CertPool // Load CA certificates caCertificate, ok := os.LookupEnv(envVarCaCertificate) @@ -74,7 +88,7 @@ func setupTlsCentralSystem() ocpp2.CSMS { ClientAuth: tls.RequireAndVerifyClientCert, ClientCAs: certPool, })) - return ocpp2.NewCSMS(nil, server) + return ocpp2.NewCSMS(nil, server, log) } // Run for every connected Charging Station, to simulate some functionality @@ -224,10 +238,13 @@ func exampleRoutine(chargingStationID string, handler *CSMSHandler) { } } var currentTx int + handler.mu.RLock() for txID := range handler.chargingStations[chargingStationID].transactions { currentTx = txID break } + handler.mu.RUnlock() + e = csms.SetDisplayMessage(chargingStationID, cb7, display.MessageInfo{ ID: 42, Priority: display.MessagePriorityInFront, @@ -246,8 +263,56 @@ func exampleRoutine(chargingStationID string, handler *CSMSHandler) { // Finish simulation } +// sets up OTLP metrics exporter +func setupMetrics(ctx context.Context, address string) error { + grpcOpts := []grpc.DialOption{ + grpc.WithTransportCredentials(insecure.NewCredentials()), + } + + client, err := grpc.NewClient(address, grpcOpts...) + if err != nil { + return errors.Wrap(err, "failed to create gRPC connection to collector") + } + + exporter, err := otlpmetricgrpc.New(ctx, otlpmetricgrpc.WithGRPCConn(client)) + if err != nil { + return errors.Wrap(err, "failed to create otlp metric exporter") + } + + resource, err := resource.New(ctx, + resource.WithAttributes( + semconv.ServiceNameKey.String("csms-demo"), + semconv.ServiceVersionKey.String("example"), + ), + resource.WithFromEnv(), + resource.WithContainer(), + resource.WithOS(), + resource.WithOSType(), + resource.WithHost(), + ) + if err != nil { + return errors.Wrap(err, "failed to create resource") + } + + meterProvider := metricsdk.NewMeterProvider( + metricsdk.WithReader( + metricsdk.NewPeriodicReader( + exporter, + metricsdk.WithInterval(100*time.Millisecond), + ), + ), + metricsdk.WithResource(resource), + ) + + otel.SetMeterProvider(meterProvider) + return nil +} + // Start function func main() { + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill) + defer cancel() + // Load config from ENV var listenPort = defaultListenPort port, _ := os.LookupEnv(envVarServerPort) @@ -256,15 +321,59 @@ func main() { } else { log.Printf("no valid %v environment variable found, using default port", envVarServerPort) } + + // Setup metrics if enabled + if t, _ := os.LookupEnv(envVarMetricsEnabled); t == "true" { + address, _ := os.LookupEnv(envVarMetricsAddress) + if err := setupMetrics(ctx, address); err != nil { + log.Error(err) + return + } + } + + if t, _ := os.LookupEnv(envProfilingEnabled); t == "true" { + address, _ := os.LookupEnv(envPyroscopeAddress) + profiler, err := pyroscope.Start(pyroscope.Config{ + ApplicationName: "ocpp201.central_system_sim", + ServerAddress: address, + ProfileTypes: []pyroscope.ProfileType{ + pyroscope.ProfileCPU, + pyroscope.ProfileInuseObjects, + pyroscope.ProfileAllocObjects, + pyroscope.ProfileInuseSpace, + pyroscope.ProfileAllocSpace, + pyroscope.ProfileGoroutines, + pyroscope.ProfileMutexCount, + pyroscope.ProfileMutexDuration, + pyroscope.ProfileBlockCount, + pyroscope.ProfileBlockDuration, + }, + }) + if err != nil { + log.Error(err) + return + } + + defer func() { + profiler.Flush(true) + _ = profiler.Stop() + }() + } + // Check if TLS enabled t, _ := os.LookupEnv(envVarTls) tlsEnabled, _ := strconv.ParseBool(t) + var err error // Prepare OCPP 1.6 central system if tlsEnabled { - csms = setupTlsCentralSystem() + csms, err = setupTlsCentralSystem() } else { - csms = setupCentralSystem() + csms, err = setupCentralSystem() + } + if err != nil { + log.Fatalf("couldn't create CSMS: %v", err) } + // Support callbacks for all OCPP 2.0.1 profiles handler := &CSMSHandler{chargingStations: map[string]*ChargingStationState{}} csms.SetAuthorizationHandler(handler) @@ -278,20 +387,31 @@ func main() { csms.SetReservationHandler(handler) csms.SetTariffCostHandler(handler) csms.SetTransactionsHandler(handler) + // Add handlers for dis/connection of charging stations csms.SetNewChargingStationHandler(func(chargingStation ocpp2.ChargingStationConnection) { + handler.mu.Lock() handler.chargingStations[chargingStation.ID()] = &ChargingStationState{connectors: map[int]*ConnectorInfo{}, transactions: map[int]*TransactionInfo{}} + handler.mu.Unlock() + log.WithField("client", chargingStation.ID()).Info("new charging station connected") go exampleRoutine(chargingStation.ID(), handler) }) csms.SetChargingStationDisconnectedHandler(func(chargingStation ocpp2.ChargingStationConnection) { log.WithField("client", chargingStation.ID()).Info("charging station disconnected") + handler.mu.Lock() delete(handler.chargingStations, chargingStation.ID()) + handler.mu.Unlock() }) - ocppj.SetLogger(log) + // Run CSMS log.Infof("starting CSMS on port %v", listenPort) - csms.Start(listenPort, "/{ws}") + go csms.Start(listenPort, "/{ws}") + + <-ctx.Done() + // Shutdown CSMS + log.Info("stopping CSMS") + csms.Stop() log.Info("stopped CSMS") } diff --git a/example/2.0.1/csms/data_handler.go b/example/2.0.1/csms/data_handler.go index 8d0c173e..4158fe57 100644 --- a/example/2.0.1/csms/data_handler.go +++ b/example/2.0.1/csms/data_handler.go @@ -2,7 +2,7 @@ package main import ( "encoding/json" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/data" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/data" ) type DataSample struct { diff --git a/example/2.0.1/csms/diagnostics_handler.go b/example/2.0.1/csms/diagnostics_handler.go index d6534ffc..838eb017 100644 --- a/example/2.0.1/csms/diagnostics_handler.go +++ b/example/2.0.1/csms/diagnostics_handler.go @@ -1,6 +1,6 @@ package main -import "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" +import "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" func (c *CSMSHandler) OnLogStatusNotification(chargingStationID string, request *diagnostics.LogStatusNotificationRequest) (response *diagnostics.LogStatusNotificationResponse, err error) { logDefault(chargingStationID, request.GetFeatureName()).Infof("log upload status: %v", request.Status) diff --git a/example/2.0.1/csms/display_handler.go b/example/2.0.1/csms/display_handler.go index 5472b1d8..aadd045d 100644 --- a/example/2.0.1/csms/display_handler.go +++ b/example/2.0.1/csms/display_handler.go @@ -1,7 +1,7 @@ package main import ( - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/display" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/display" ) func (c *CSMSHandler) OnNotifyDisplayMessages(chargingStationID string, request *display.NotifyDisplayMessagesRequest) (response *display.NotifyDisplayMessagesResponse, err error) { diff --git a/example/2.0.1/csms/firmware_handler.go b/example/2.0.1/csms/firmware_handler.go index ed613efc..ec57676e 100644 --- a/example/2.0.1/csms/firmware_handler.go +++ b/example/2.0.1/csms/firmware_handler.go @@ -2,10 +2,14 @@ package main import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/firmware" + + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/firmware" ) func (c *CSMSHandler) OnFirmwareStatusNotification(chargingStationID string, request *firmware.FirmwareStatusNotificationRequest) (response *firmware.FirmwareStatusNotificationResponse, err error) { + c.mu.RLock() + defer c.mu.RUnlock() + info, ok := c.chargingStations[chargingStationID] if !ok { err = fmt.Errorf("unknown charging station %v", chargingStationID) diff --git a/example/2.0.1/csms/handler.go b/example/2.0.1/csms/handler.go index e420814d..9c4c8155 100644 --- a/example/2.0.1/csms/handler.go +++ b/example/2.0.1/csms/handler.go @@ -1,11 +1,13 @@ package main import ( + "sync" + "github.com/sirupsen/logrus" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/availability" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/availability" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // TransactionInfo contains info about a transaction @@ -53,6 +55,7 @@ func (s *ChargingStationState) getConnector(id int) *ConnectorInfo { // CSMSHandler contains some simple state that a CSMS may want to keep. // In production this will typically be replaced by database/API calls. type CSMSHandler struct { + mu sync.RWMutex chargingStations map[string]*ChargingStationState } diff --git a/example/2.0.1/csms/iso15118_handler.go b/example/2.0.1/csms/iso15118_handler.go index 73beed29..5873c10c 100644 --- a/example/2.0.1/csms/iso15118_handler.go +++ b/example/2.0.1/csms/iso15118_handler.go @@ -1,9 +1,9 @@ package main import ( - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/iso15118" - "github.com/lorenzodonini/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/iso15118" + "github.com/xBlaz3kx/ocpp-go/ocppj" ) func (c *CSMSHandler) OnGet15118EVCertificate(chargingStationID string, request *iso15118.Get15118EVCertificateRequest) (response *iso15118.Get15118EVCertificateResponse, err error) { diff --git a/example/2.0.1/csms/meter_handler.go b/example/2.0.1/csms/meter_handler.go index d1b58014..733ac8d7 100644 --- a/example/2.0.1/csms/meter_handler.go +++ b/example/2.0.1/csms/meter_handler.go @@ -1,6 +1,6 @@ package main -import "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/meter" +import "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/meter" func (c *CSMSHandler) OnMeterValues(chargingStationID string, request *meter.MeterValuesRequest) (response *meter.MeterValuesResponse, err error) { logDefault(chargingStationID, request.GetFeatureName()).Infof("received meter values for EVSE %v. Meter values:\n", request.EvseID) diff --git a/example/2.0.1/csms/provisioning_handler.go b/example/2.0.1/csms/provisioning_handler.go index 08fff4fc..f8e60218 100644 --- a/example/2.0.1/csms/provisioning_handler.go +++ b/example/2.0.1/csms/provisioning_handler.go @@ -1,8 +1,8 @@ package main import ( - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "time" ) diff --git a/example/2.0.1/csms/reservation_handler.go b/example/2.0.1/csms/reservation_handler.go index be6be7d7..797d0480 100644 --- a/example/2.0.1/csms/reservation_handler.go +++ b/example/2.0.1/csms/reservation_handler.go @@ -1,6 +1,6 @@ package main -import "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/reservation" +import "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/reservation" func (c *CSMSHandler) OnReservationStatusUpdate(chargingStationID string, request *reservation.ReservationStatusUpdateRequest) (response *reservation.ReservationStatusUpdateResponse, err error) { logDefault(chargingStationID, request.GetFeatureName()).Infof("updated status of reservation %v to: %v", request.ReservationID, request.Status) diff --git a/example/2.0.1/csms/security_handler.go b/example/2.0.1/csms/security_handler.go index e7f7f55a..561dc9c7 100644 --- a/example/2.0.1/csms/security_handler.go +++ b/example/2.0.1/csms/security_handler.go @@ -1,9 +1,9 @@ package main import ( - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/security" - "github.com/lorenzodonini/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/security" + "github.com/xBlaz3kx/ocpp-go/ocppj" ) func (c *CSMSHandler) OnSecurityEventNotification(chargingStationID string, request *security.SecurityEventNotificationRequest) (response *security.SecurityEventNotificationResponse, err error) { diff --git a/example/2.0.1/csms/smartcharging_handler.go b/example/2.0.1/csms/smartcharging_handler.go index f46bfc55..5cacce57 100644 --- a/example/2.0.1/csms/smartcharging_handler.go +++ b/example/2.0.1/csms/smartcharging_handler.go @@ -1,9 +1,9 @@ package main import ( - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocppj" ) func (c *CSMSHandler) OnClearedChargingLimit(chargingStationID string, request *smartcharging.ClearedChargingLimitRequest) (response *smartcharging.ClearedChargingLimitResponse, err error) { diff --git a/example/2.0.1/csms/transactions_handler.go b/example/2.0.1/csms/transactions_handler.go index b36ed2b1..04c94334 100644 --- a/example/2.0.1/csms/transactions_handler.go +++ b/example/2.0.1/csms/transactions_handler.go @@ -1,6 +1,6 @@ package main -import "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/transactions" +import "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/transactions" func (c *CSMSHandler) OnTransactionEvent(chargingStationID string, request *transactions.TransactionEventRequest) (response *transactions.TransactionEventResponse, err error) { switch request.EventType { diff --git a/example/2.0.1/docker-compose.k6-ci.yml b/example/2.0.1/docker-compose.k6-ci.yml new file mode 100644 index 00000000..39ea205b --- /dev/null +++ b/example/2.0.1/docker-compose.k6-ci.yml @@ -0,0 +1,28 @@ +version: '3.9' + +services: + csms: + hostname: csms_201 + ports: + - "8888:8887" + + k6: + image: grafana/k6:latest + # Run the performance tests + user: ${UID}:${GID} + depends_on: + - csms + networks: + - sim + command: run /scripts/rapid-connect-disconnect.ts --vus 10 --duration 30s --out json=ocpp_201.json --summary-export=summary_201.json + volumes: + - ./k6:/scripts + - ./results:/home/k6 + environment: + # To prevent clashing in CI + - WS_PORT=8888 + - WS_HOST=csms_201 + +networks: + sim: + driver: bridge diff --git a/example/2.0.1/docker-compose.k6.yml b/example/2.0.1/docker-compose.k6.yml new file mode 100644 index 00000000..bb41edfa --- /dev/null +++ b/example/2.0.1/docker-compose.k6.yml @@ -0,0 +1,42 @@ +version: '3.9' +services: + cpms: + build: + context: ../.. + dockerfile: example/2.0.1/csms/Dockerfile + image: ldonini/ocpp2.0.1-cpms:latest + container_name: cpms + environment: + - METRICS_ENABLED=${METRICS_ENABLED:-true} + - METRICS_ADDRESS=${METRICS_ADDRESS:-lgtm-stack:4317} + - PROFILING_ENABLED=${PROFILING_ENABLED:-true} + - PYROSCOPE_ADDRESS=${PYROSCOPE_ADDRESS:-http://lgtm-stack:4040} + - SERVER_LISTEN_PORT=8887 + ports: + - "8887:8887" + networks: + - sim + tty: true + + k6: + image: grafana/k6:latest + container_name: k6 + # Run the performance tests + command: run -o experimental-prometheus-rw /scripts/rapid-connect-disconnect.ts --vus 10 --duration 1m + depends_on: + - cpms + - grafana-lgtm-stack + networks: + - sim + environment: + # Performance metrics will be pushed to Prometheus via the LGTM stack + - K6_OUTPUTS=prometheus-remote + - K6_PROMETHEUS_RW_SERVER_URL=http://lgtm-stack:9090/api/v1/write + - K6_PROMETHEUS_RW_PUSH_INTERVAL=10s + - K6_PROMETHEUS_RW_TREND_STATS=p(90),p(95),max + volumes: + - ./k6:/scripts + +networks: + sim: + driver: bridge diff --git a/example/2.0.1/docker-compose.tls.yml b/example/2.0.1/docker-compose.tls.yml index be3ead8d..6f86c5e6 100644 --- a/example/2.0.1/docker-compose.tls.yml +++ b/example/2.0.1/docker-compose.tls.yml @@ -15,6 +15,8 @@ services: - CA_CERTIFICATE_PATH=/usr/local/share/certs/ca.crt - SERVER_CERTIFICATE_PATH=/usr/local/share/certs/csms.crt - SERVER_CERTIFICATE_KEY_PATH=/usr/local/share/certs/csms.key + - METRICS_ENABLED=${METRICS_ENABLED:-false} + - METRICS_ADDRESS=${METRICS_ADDRESS:-lgtm-stack:4317} ports: - "443:443" networks: diff --git a/example/2.0.1/docker-compose.yml b/example/2.0.1/docker-compose.yml index 21441985..5b59ac87 100644 --- a/example/2.0.1/docker-compose.yml +++ b/example/2.0.1/docker-compose.yml @@ -3,20 +3,22 @@ services: csms: build: context: ../.. - dockerfile: csms/Dockerfile + dockerfile: example/2.0.1/csms/Dockerfile image: ldonini/ocpp2.0.1-csms:latest container_name: csms environment: - SERVER_LISTEN_PORT=8887 + - METRICS_ENABLED=${METRICS_ENABLED:-false} + - METRICS_ADDRESS=${METRICS_ADDRESS:-lgtm-stack:4317} ports: - "8887:8887" networks: - sim - tty: true + # tty: true charging-station: build: context: ../.. - dockerfile: chargingstation/Dockerfile + dockerfile: example/2.0.1/chargingstation/Dockerfile image: ldonini/ocpp2.0.1-chargingstation:latest container_name: charging-station environment: @@ -24,7 +26,7 @@ services: - CSMS_URL=ws://csms:8887 networks: - sim - tty: true + # tty: true networks: sim: diff --git a/example/2.0.1/k6/rapid-connect-disconnect.ts b/example/2.0.1/k6/rapid-connect-disconnect.ts new file mode 100644 index 00000000..660dcc03 --- /dev/null +++ b/example/2.0.1/k6/rapid-connect-disconnect.ts @@ -0,0 +1,388 @@ +import {randomIntBetween, randomString} from 'https://jslib.k6.io/k6-utils/1.2.0/index.js'; +import ws from 'k6/ws'; +import {check, sleep} from 'k6'; + +// OCPP 2.0.1 Core profile message structure constants +const MESSAGE_TYPE = { + CALL: 2, + CALL_RESULT: 3, + CALL_ERROR: 4 +}; + +const ACTIONS = { + BOOT_NOTIFICATION: 'BootNotification', + HEARTBEAT: 'Heartbeat', + STATUS_NOTIFICATION: 'StatusNotification', + AUTHORIZE: 'Authorize', + TRANSACTION_EVENT: 'TransactionEvent', + METER_VALUES: 'MeterValues' +}; + +// OCPP 2.0.1 Core profile specific constants +const BOOT_REASONS = [ + 'ApplicationReset', + 'FirmwareUpdate', + 'LocalReset', + 'PowerUp', + 'RemoteReset', + 'ScheduledReset', + 'Triggered', + 'Unknown', + 'Watchdog' +]; + +const CONNECTOR_STATUSES = [ + 'Available', + 'Occupied', + 'Reserved', + 'Unavailable', + 'Faulted' +]; + +// Core profile incoming request actions from central system +const INCOMING_ACTIONS = { + CHANGE_AVAILABILITY: 'ChangeAvailability', + CHANGE_CONFIGURATION: 'ChangeConfiguration', + CLEAR_CACHE: 'ClearCache', + DATA_TRANSFER: 'DataTransfer', + GET_CONFIGURATION: 'GetConfiguration', + RESET: 'Reset', + UNLOCK_CONNECTOR: 'UnlockConnector', + REMOTE_START_TRANSACTION: 'RemoteStartTransaction', + REMOTE_STOP_TRANSACTION: 'RemoteStopTransaction' +}; + +// Generate unique charging station ID +function generateChargingStationId() { + return `CS_${__VU}_${randomString(8)}`; +} + +// Generate OCPP 2.0.1 Core profile BootNotification message +function createBootNotification(chargingStationId: string) { + const messageId = randomString(8); + const payload = { + reason: BOOT_REASONS[randomIntBetween(0, BOOT_REASONS.length - 1)], + chargingStation: { + serialNumber: chargingStationId, + model: `Model_${randomString(5)}`, + vendorName: `Vendor_${randomString(5)}`, + firmwareVersion: `v${randomIntBetween(1, 9)}.${randomIntBetween(0, 9)}.${randomIntBetween(0, 9)}`, + modem: { + iccid: randomString(20), + imsi: randomString(15) + } + } + }; + + return JSON.stringify([MESSAGE_TYPE.CALL, messageId, ACTIONS.BOOT_NOTIFICATION, payload]); +} + +// Generate OCPP 2.0.1 Core profile Heartbeat message +function createHeartbeat() { + const messageId = randomString(8); + return JSON.stringify([MESSAGE_TYPE.CALL, messageId, ACTIONS.HEARTBEAT, {}]); +} + +// Generate OCPP 2.0.1 Core profile StatusNotification message +function createStatusNotification(chargingStationId: string, evseId: number, connectorId: number, status: string) { + const messageId = randomString(8); + const payload = { + evse: { + id: evseId, + connectorId: connectorId + }, + timestamp: new Date().toISOString(), + connectorStatus: status + }; + + return JSON.stringify([MESSAGE_TYPE.CALL, messageId, ACTIONS.STATUS_NOTIFICATION, payload]); +} + +// Generate OCPP 2.0.1 Core profile Authorize message +function createAuthorize(idToken: string) { + const messageId = randomString(8); + const payload = { + idToken: { + idToken: idToken, + type: 'ISO14443' + } + }; + + return JSON.stringify([MESSAGE_TYPE.CALL, messageId, ACTIONS.AUTHORIZE, payload]); +} + +// Generate OCPP 2.0.1 Core profile TransactionEvent message +function createTransactionEvent(chargingStationId: string, evseId: number, transactionId: string, eventType: string) { + const messageId = randomString(8); + const payload = { + eventType: eventType, + timestamp: new Date().toISOString(), + triggerReason: 'Authorized', + seqNo: randomIntBetween(1, 1000), + transactionInfo: { + transactionId: transactionId, + chargingState: eventType === 'Started' ? 'Charging' : 'Idle' + }, + evse: { + id: evseId, + connectorId: 1 + } + }; + + return JSON.stringify([MESSAGE_TYPE.CALL, messageId, ACTIONS.TRANSACTION_EVENT, payload]); +} + +// Generate OCPP 2.0.1 Core profile MeterValues message +function createMeterValues(evseId: number, transactionId?: string) { + const messageId = randomString(8); + const payload = { + evseId: evseId, + transactionId: transactionId, + meterValue: [{ + timestamp: new Date().toISOString(), + sampledValue: [{ + value: randomIntBetween(0, 100000), + context: 'Sample.Periodic', + measurand: 'Energy.Active.Import.Register', + unitOfMeasure: { + unit: 'Wh', + multiplier: 0 + } + }] + }] + }; + + return JSON.stringify([MESSAGE_TYPE.CALL, messageId, ACTIONS.METER_VALUES, payload]); +} + +// Generate OCPP 2.0.1 Core profile CallResult response +function createCallResult(messageId: string, payload: any) { + return JSON.stringify([MESSAGE_TYPE.CALL_RESULT, messageId, payload]); +} + +// Generate OCPP 2.0.1 Core profile CallError response +function createCallError(messageId: string, errorCode: string, errorDescription: string) { + return JSON.stringify([MESSAGE_TYPE.CALL_ERROR, messageId, errorCode, errorDescription, {}]); +} + +// Handle incoming Core profile ChangeAvailability request +function handleChangeAvailability(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile ChangeConfiguration request +function handleChangeConfiguration(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile ClearCache request +function handleClearCache(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile DataTransfer request +function handleDataTransfer(request: any) { + return { + status: 'Accepted', + data: `Response to ${request.vendorId}:${request.messageId || 'default'}` + }; +} + +// Handle incoming Core profile GetConfiguration request +function handleGetConfiguration(request: any) { + return { + configurationKey: [ + { + key: 'HeartbeatInterval', + readonly: false, + value: '60' + }, + { + key: 'ConnectionTimeOut', + readonly: false, + value: '60' + } + ], + unknownKey: [] + }; +} + +// Handle incoming Core profile Reset request +function handleReset(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile UnlockConnector request +function handleUnlockConnector(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile RemoteStartTransaction request +function handleRemoteStartTransaction(request: any) { + return { + status: 'Accepted' + }; +} + +// Handle incoming Core profile RemoteStopTransaction request +function handleRemoteStopTransaction(request: any) { + return { + status: 'Accepted' + }; +} + +// Route incoming Core profile requests to appropriate handlers +function handleIncomingRequest(action: string, payload: any, messageId: string) { + let response; + + try { + switch (action) { + case INCOMING_ACTIONS.CHANGE_AVAILABILITY: + response = handleChangeAvailability(payload); + break; + case INCOMING_ACTIONS.CHANGE_CONFIGURATION: + response = handleChangeConfiguration(payload); + break; + case INCOMING_ACTIONS.CLEAR_CACHE: + response = handleClearCache(payload); + break; + case INCOMING_ACTIONS.DATA_TRANSFER: + response = handleDataTransfer(payload); + break; + case INCOMING_ACTIONS.GET_CONFIGURATION: + response = handleGetConfiguration(payload); + break; + case INCOMING_ACTIONS.RESET: + response = handleReset(payload); + break; + case INCOMING_ACTIONS.UNLOCK_CONNECTOR: + response = handleUnlockConnector(payload); + break; + case INCOMING_ACTIONS.REMOTE_START_TRANSACTION: + response = handleRemoteStartTransaction(payload); + break; + case INCOMING_ACTIONS.REMOTE_STOP_TRANSACTION: + response = handleRemoteStopTransaction(payload); + break; + default: + console.log(`VU ${__VU}: Unknown incoming action: ${action}`); + return createCallError(messageId, 'NotImplemented', `Action ${action} not implemented`); + } + + return createCallResult(messageId, response); + } catch (error) { + console.log(`VU ${__VU}: Error handling ${action}: ${error}`); + return createCallError(messageId, 'InternalError', `Failed to process ${action}`); + } +} + +export default function () { + const chargingStationId = generateChargingStationId(); + + // Configurable WebSocket URL from environment variables + const wsHost = __ENV.WS_HOST || 'central-system'; + const wsPort = __ENV.WS_PORT || '8887'; + const wsProtocol = __ENV.WS_PROTOCOL || 'ws'; + const wsPath = __ENV.WS_PATH || ''; + + const url = `${wsProtocol}://${wsHost}:${wsPort}${wsPath}/${chargingStationId}`; + + console.log(`VU ${__VU}: Connecting to ${url}`); + + const params = { + // OCPP 2.0.1 requires specific WebSocket subprotocol + headers: { + 'Sec-WebSocket-Protocol': 'ocpp2.0.1' + } + }; + + // Track connection metrics + const startTime = Date.now(); + let messageCount = 0; + let reconnectCount = 0; + const maxReconnects = randomIntBetween(3, 8); // Random number of reconnections per VU + + // Main connection loop with rapid connect/disconnect + for (let i = 0; i < maxReconnects; i++) { + const res = ws.connect(url, params, function (socket) { + const connectionStart = Date.now(); + + socket.on('open', function open() { + const connectTime = Date.now() - connectionStart; + console.log(`VU ${__VU}: Connected in ${connectTime}ms (attempt ${i + 1}/${maxReconnects})`); + + // Send BootNotification immediately after connection + const bootMsg = createBootNotification(chargingStationId); + socket.send(bootMsg); + messageCount++; + + // Disconnect after random time (100-200ms) + const disconnectDelay = randomIntBetween(100, 200); + setTimeout(() => { + console.log(`VU ${__VU}: Disconnecting after ${disconnectDelay}ms`); + socket.close(); + }, disconnectDelay); + }); + + socket.on('message', function (message) { + try { + const data = JSON.parse(message); + + if (data[0] === MESSAGE_TYPE.CALL_RESULT) { + console.log(`VU ${__VU}: Received response for message ${data[1]}`); + } else if (data[0] === MESSAGE_TYPE.CALL_ERROR) { + console.log(`VU ${__VU}: Received error for message ${data[1]}: ${data[2]}`); + } else if (data[0] === MESSAGE_TYPE.CALL) { + // Handle incoming request from central system + const messageId = data[1]; + const action = data[2]; + const payload = data[3] || {}; + + console.log(`VU ${__VU}: Received incoming request: ${action} (ID: ${messageId})`); + + // Generate and send response + const response = handleIncomingRequest(action, payload, messageId); + socket.send(response); + + // Track incoming request handling + messageCount++; + } + } catch (e) { + console.log(`VU ${__VU}: Received non-JSON message: ${message}`); + } + }); + + socket.on('close', function () { + const totalTime = Date.now() - connectionStart; + console.log(`VU ${__VU}: Disconnected after ${totalTime}ms`); + reconnectCount++; + }); + + socket.on('error', function (error) { + console.log(`VU ${__VU}: WebSocket error: ${error}`); + }); + }); + + // Verify connection was successful + check(res, { + 'Connected successfully': (r) => r && r.status === 101, + 'Connection time < 200ms': (r) => r && (Date.now() - startTime) < 200 + }); + + // Small delay between reconnections to avoid overwhelming the server + sleep(randomIntBetween(50, 100) / 1000); + } + + // Final metrics + console.log(`VU ${__VU}: Completed ${reconnectCount} connections with ${messageCount} messages in ${Date.now() - startTime}ms`); +} diff --git a/example/docker-compose.observability.yaml b/example/docker-compose.observability.yaml new file mode 100644 index 00000000..1fb7eaae --- /dev/null +++ b/example/docker-compose.observability.yaml @@ -0,0 +1,36 @@ +services: + # Grafana stack is used for CPMS observability purposes. + # For capturing metrics, you can configure the exporters via environment variables + # to either Prometheus or OTel Collector (default). + # Prometheus needs to be configured so it can scrape your application instance(s). + # To simplify testing and development, we will use the Otel collector as the default. + # Your CPMS backend will push the metrics in OTLP format to the Otel collector. + # The collector comes as a part of the LGTM stack. + grafana-lgtm-stack: + image: grafana/otel-lgtm:latest + container_name: lgtm-stack + hostname: lgtm-stack + #environment: + # - GF_SECURITY_ADMIN_USER="admin" + # - GF_SECURITY_ADMIN_PASSWORD="admin" + volumes: + - prometheus:/prometheus + - loki:/data/loki + - grafana:/var/lib/grafana + - ./grafana-provision/grafana:/etc/grafana/provisioning + networks: + - sim + ports: + - "3000:3000" # Grafana + - "4317:4317" # OTLP gRPC receiver + - "4040:4040" # Pyroscope + - "9090:9090" # Prometheus + +networks: + sim: + driver: bridge + +volumes: + prometheus: + loki: + grafana: \ No newline at end of file diff --git a/example/grafana-provision/grafana/datasources/pyroscope.yaml b/example/grafana-provision/grafana/datasources/pyroscope.yaml new file mode 100644 index 00000000..984951b1 --- /dev/null +++ b/example/grafana-provision/grafana/datasources/pyroscope.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: 1 +datasources: + - uid: local-pyroscope + type: grafana-pyroscope-datasource + name: Pyroscope + url: http://pyroscope:4040 + jsonData: + keepCookies: [pyroscope_git_session] \ No newline at end of file diff --git a/example/grafana-provision/grafana/plugins/profiles.yaml b/example/grafana-provision/grafana/plugins/profiles.yaml new file mode 100644 index 00000000..29001ffe --- /dev/null +++ b/example/grafana-provision/grafana/plugins/profiles.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: 1 +apps: + - type: grafana-pyroscope-app + jsonData: + backendUrl: http://pyroscope:4040 + secureJsonData: \ No newline at end of file diff --git a/example/grafana-provision/pyroscope/cfg.yaml b/example/grafana-provision/pyroscope/cfg.yaml new file mode 100644 index 00000000..da27a98e --- /dev/null +++ b/example/grafana-provision/pyroscope/cfg.yaml @@ -0,0 +1,2 @@ +self_profiling: + use_k6_middleware: false \ No newline at end of file diff --git a/go.mod b/go.mod index e09ef029..fdbffe8d 100644 --- a/go.mod +++ b/go.mod @@ -1,21 +1,51 @@ -module github.com/lorenzodonini/ocpp-go +module github.com/xBlaz3kx/ocpp-go -go 1.16 +go 1.25 require ( github.com/Shopify/toxiproxy v2.1.4+incompatible + github.com/agrison/go-commons-lang v0.0.0-20240106075236-2e001e6401ef github.com/caarlos0/env/v11 v11.3.1 - github.com/go-playground/locales v0.12.1 // indirect github.com/go-playground/universal-translator v0.16.0 github.com/gorilla/mux v1.8.1 github.com/gorilla/websocket v1.5.3 - github.com/kr/pretty v0.1.0 // indirect - github.com/leodido/go-urn v1.1.0 // indirect + github.com/grafana/pyroscope-go v1.2.4 + github.com/pkg/errors v0.9.1 github.com/relvacode/iso8601 v1.6.0 - github.com/sirupsen/logrus v1.4.2 - github.com/stretchr/testify v1.8.0 - golang.org/x/sys v0.0.0-20220804214406-8e32c043e418 // indirect - gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect + github.com/samber/lo v1.46.0 + github.com/sirupsen/logrus v1.8.3 + github.com/stretchr/testify v1.10.0 + go.opentelemetry.io/otel v1.34.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 + go.opentelemetry.io/otel/metric v1.34.0 + go.opentelemetry.io/otel/sdk v1.34.0 + go.opentelemetry.io/otel/sdk/metric v1.34.0 + google.golang.org/grpc v1.70.0 + gopkg.in/go-playground/validator.v9 v9.31.0 +) + +require ( + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-playground/locales v0.12.1 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect + github.com/klauspost/compress v1.17.8 // indirect + github.com/leodido/go-urn v1.1.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/otel/trace v1.34.0 // indirect + go.opentelemetry.io/proto/otlp v1.5.0 // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect + google.golang.org/protobuf v1.36.3 // indirect gopkg.in/go-playground/assert.v1 v1.2.1 // indirect - gopkg.in/go-playground/validator.v9 v9.30.0 + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 526046d2..da359586 100644 --- a/go.sum +++ b/go.sum @@ -1,51 +1,103 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/agrison/go-commons-lang v0.0.0-20240106075236-2e001e6401ef h1:KkznClyESbRaLmRo7Oam4vv5L4oknDK+mixJ9mypl6E= +github.com/agrison/go-commons-lang v0.0.0-20240106075236-2e001e6401ef/go.mod h1:u+Zwm0OKtJAGx+DXcmp2NNwZ0GKtV80ipbF/uhKhQdw= github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5mCA= github.com/caarlos0/env/v11 v11.3.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc= github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM= github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/grafana/pyroscope-go v1.2.4 h1:B22GMXz+O0nWLatxLuaP7o7L9dvP0clLvIpmeEQQM0Q= +github.com/grafana/pyroscope-go v1.2.4/go.mod h1:zzT9QXQAp2Iz2ZdS216UiV8y9uXJYQiGE1q8v1FyhqU= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8= github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/relvacode/iso8601 v1.6.0 h1:eFXUhMJN3Gz8Rcq82f9DTMW0svjtAVuIEULglM7QHTU= github.com/relvacode/iso8601 v1.6.0/go.mod h1:FlNp+jz+TXpyRqgmM7tnzHHzBnz776kmAH2h3sZCn0I= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ= +github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= +github.com/sirupsen/logrus v1.8.3 h1:DBBfY8eMYazKEJHb3JKpSPfpgd2mBCoNFlQx6C5fftU= +github.com/sirupsen/logrus v1.8.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20220804214406-8e32c043e418 h1:9vYwv7OjYaky/tlAeD7C4oC9EsPTlaFl1H2jS++V+ME= -golang.org/x/sys v0.0.0-20220804214406-8e32c043e418/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 h1:ajl4QczuJVA2TU9W9AGw++86Xga/RKt//16z/yxPgdk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0/go.mod h1:Vn3/rlOJ3ntf/Q3zAI0V5lDnTbHGaUsNUeF6nZmm7pA= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= +go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f h1:gap6+3Gk41EItBuyi4XX/bp4oqJ3UwuIMl25yGinuAA= +google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:Ic02D47M+zbarjYYUlK57y316f2MoN0gjAwI3f2S95o= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= +google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= +google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= +google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= +google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v9 v9.30.0 h1:Wk0Z37oBmKj9/n+tPyBHZmeL19LaCoK3Qq48VwYENss= -gopkg.in/go-playground/validator.v9 v9.30.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= +gopkg.in/go-playground/validator.v9 v9.31.0 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+an+ZQdDaD1M= +gopkg.in/go-playground/validator.v9 v9.31.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/callbackqueue/callbackqueue.go b/internal/callbackqueue/callbackqueue.go index e5820e70..da31f917 100644 --- a/internal/callbackqueue/callbackqueue.go +++ b/internal/callbackqueue/callbackqueue.go @@ -3,7 +3,7 @@ package callbackqueue import ( "sync" - "github.com/lorenzodonini/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp" ) type CallbackQueue struct { diff --git a/internal/callbackqueue/callbackqueue_test.go b/internal/callbackqueue/callbackqueue_test.go new file mode 100644 index 00000000..626a945b --- /dev/null +++ b/internal/callbackqueue/callbackqueue_test.go @@ -0,0 +1,491 @@ +package callbackqueue + +import ( + "errors" + "sync" + "sync/atomic" + "testing" + + "github.com/stretchr/testify/suite" + "github.com/xBlaz3kx/ocpp-go/ocpp" +) + +// MockResponse is a simple mock implementation of ocpp.Response for testing +type MockResponse struct { + Value string +} + +func (m *MockResponse) GetFeatureName() string { + return "Mock" +} + +// CallbackQueueTestSuite contains tests for the CallbackQueue +type CallbackQueueTestSuite struct { + suite.Suite + queue CallbackQueue +} + +func (suite *CallbackQueueTestSuite) SetupTest() { + suite.queue = New() +} + +// TestTryQueueSuccess verifies that TryQueue succeeds when try() returns nil +func (suite *CallbackQueueTestSuite) TestTryQueueSuccess() { + id := "test-id" + callbackCalled := atomic.Bool{} + var receivedResponse ocpp.Response + var receivedError error + + callback := func(confirmation ocpp.Response, err error) { + callbackCalled.Store(true) + receivedResponse = confirmation + receivedError = err + } + + try := func() error { + return nil // Success + } + + err := suite.queue.TryQueue(id, try, callback) + suite.Require().NoError(err) + suite.Assert().False(callbackCalled.Load(), "Callback should not be called yet") + + // Dequeue and invoke callback + cb, ok := suite.queue.Dequeue(id) + suite.Require().True(ok) + suite.Require().NotNil(cb) + + mockResp := &MockResponse{Value: "test"} + cb(mockResp, nil) + + suite.Assert().True(callbackCalled.Load()) + suite.Assert().Equal(mockResp, receivedResponse) + suite.Assert().Nil(receivedError) +} + +// TestTryQueueFailure verifies that TryQueue removes callback when try() returns error +func (suite *CallbackQueueTestSuite) TestTryQueueFailure() { + id := "test-id" + callbackCalled := atomic.Bool{} + callback := func(confirmation ocpp.Response, err error) { + callbackCalled.Store(true) + } + + try := func() error { + return errors.New("try failed") + } + + err := suite.queue.TryQueue(id, try, callback) + suite.Require().Error(err) + suite.Assert().Equal("try failed", err.Error()) + suite.Assert().False(callbackCalled.Load(), "Callback should not be called") + + // Verify callback was removed from queue + _, ok := suite.queue.Dequeue(id) + suite.Assert().False(ok, "Callback should have been removed") +} + +// TestDequeueEmpty verifies that Dequeue returns false for empty queue +func (suite *CallbackQueueTestSuite) TestDequeueEmpty() { + id := "non-existent" + + cb, ok := suite.queue.Dequeue(id) + suite.Assert().False(ok) + suite.Assert().Nil(cb) +} + +// TestDequeueFIFO verifies that callbacks are dequeued in FIFO order +func (suite *CallbackQueueTestSuite) TestDequeueFIFO() { + id := "test-id" + callbacksCalled := make([]int, 0) + var mu sync.Mutex + + // Queue multiple callbacks + for i := 0; i < 5; i++ { + index := i + callback := func(confirmation ocpp.Response, err error) { + mu.Lock() + callbacksCalled = append(callbacksCalled, index) + mu.Unlock() + } + + try := func() error { + return nil + } + + err := suite.queue.TryQueue(id, try, callback) + suite.Require().NoError(err) + } + + // Dequeue and invoke callbacks in order + for i := 0; i < 5; i++ { + cb, ok := suite.queue.Dequeue(id) + suite.Require().True(ok) + suite.Require().NotNil(cb) + cb(nil, nil) + } + + // Verify FIFO order + mu.Lock() + suite.Require().Len(callbacksCalled, 5) + for i := 0; i < 5; i++ { + suite.Assert().Equal(i, callbacksCalled[i], "Callbacks should be called in FIFO order") + } + mu.Unlock() + + // Queue should be empty now + _, ok := suite.queue.Dequeue(id) + suite.Assert().False(ok) +} + +// TestMultipleIDs verifies that different IDs maintain separate queues +func (suite *CallbackQueueTestSuite) TestMultipleIDs() { + id1 := "id1" + id2 := "id2" + + callback1Called := atomic.Bool{} + callback2Called := atomic.Bool{} + + callback1 := func(confirmation ocpp.Response, err error) { + callback1Called.Store(true) + } + + callback2 := func(confirmation ocpp.Response, err error) { + callback2Called.Store(true) + } + + try := func() error { + return nil + } + + // Queue callbacks for different IDs + err := suite.queue.TryQueue(id1, try, callback1) + suite.Require().NoError(err) + + err = suite.queue.TryQueue(id2, try, callback2) + suite.Require().NoError(err) + + // Dequeue from id1 + cb1, ok := suite.queue.Dequeue(id1) + suite.Require().True(ok) + cb1(nil, nil) + suite.Assert().True(callback1Called.Load()) + suite.Assert().False(callback2Called.Load()) + + // Dequeue from id2 + cb2, ok := suite.queue.Dequeue(id2) + suite.Require().True(ok) + cb2(nil, nil) + suite.Assert().True(callback2Called.Load()) + + // Both queues should be empty + _, ok = suite.queue.Dequeue(id1) + suite.Assert().False(ok) + _, ok = suite.queue.Dequeue(id2) + suite.Assert().False(ok) +} + +// TestDequeueRemovesFromQueue verifies that Dequeue removes the callback from the queue +func (suite *CallbackQueueTestSuite) TestDequeueRemovesFromQueue() { + id := "test-id" + callbackCalled := atomic.Int64{} + + callback := func(confirmation ocpp.Response, err error) { + callbackCalled.Add(1) + } + + try := func() error { + return nil + } + + // Queue callback + err := suite.queue.TryQueue(id, try, callback) + suite.Require().NoError(err) + + // Dequeue first time + cb1, ok := suite.queue.Dequeue(id) + suite.Require().True(ok) + cb1(nil, nil) + suite.Assert().Equal(1, int(callbackCalled.Load())) + + // Try to dequeue again - should fail + _, ok = suite.queue.Dequeue(id) + suite.Assert().False(ok) + suite.Assert().Equal(1, int(callbackCalled.Load()), "Callback should only be called once") +} + +// TestTryQueueFailureRemovesLastCallback verifies that on failure, only the last queued callback is removed +func (suite *CallbackQueueTestSuite) TestTryQueueFailureRemovesLastCallback() { + id := "test-id" + callbacksCalled := make([]int, 0) + var mu sync.Mutex + + // Queue two callbacks successfully + for i := 0; i < 2; i++ { + index := i + callback := func(confirmation ocpp.Response, err error) { + mu.Lock() + callbacksCalled = append(callbacksCalled, index) + mu.Unlock() + } + + try := func() error { + return nil + } + + err := suite.queue.TryQueue(id, try, callback) + suite.Require().NoError(err) + } + + // Queue a third callback that fails + callback3 := func(confirmation ocpp.Response, err error) { + mu.Lock() + callbacksCalled = append(callbacksCalled, 3) + mu.Unlock() + } + + tryFail := func() error { + return errors.New("failed") + } + + err := suite.queue.TryQueue(id, tryFail, callback3) + suite.Require().Error(err) + + // First two callbacks should still be in queue + cb1, ok := suite.queue.Dequeue(id) + suite.Require().True(ok) + cb1(nil, nil) + + cb2, ok := suite.queue.Dequeue(id) + suite.Require().True(ok) + cb2(nil, nil) + + // Queue should be empty + _, ok = suite.queue.Dequeue(id) + suite.Assert().False(ok) + + // Verify only first two callbacks were called + mu.Lock() + suite.Require().Len(callbacksCalled, 2) + suite.Assert().Equal(0, callbacksCalled[0]) + suite.Assert().Equal(1, callbacksCalled[1]) + mu.Unlock() +} + +// TestConcurrentTryQueue verifies thread safety of TryQueue +func (suite *CallbackQueueTestSuite) TestConcurrentTryQueue() { + id := "test-id" + numGoroutines := 100 + var wg sync.WaitGroup + callbacksQueued := make(chan int, numGoroutines) + + // Concurrently queue callbacks + for i := 0; i < numGoroutines; i++ { + wg.Add(1) + + go func(index int) { + defer wg.Done() + callback := func(confirmation ocpp.Response, err error) { + callbacksQueued <- index + } + + try := func() error { + return nil + } + + err := suite.queue.TryQueue(id, try, callback) + suite.Require().NoError(err) + }(i) + } + + wg.Wait() + + // Dequeue all callbacks + received := make(map[int]bool) + for i := 0; i < numGoroutines; i++ { + cb, ok := suite.queue.Dequeue(id) + suite.Require().True(ok) + cb(nil, nil) + } + + // Collect all received indices + for i := 0; i < numGoroutines; i++ { + index := <-callbacksQueued + received[index] = true + } + + // Verify all callbacks were queued and dequeued + suite.Assert().Len(received, numGoroutines) + + // Queue should be empty + _, ok := suite.queue.Dequeue(id) + suite.Assert().False(ok) +} + +// TestConcurrentDequeue verifies thread safety of Dequeue +func (suite *CallbackQueueTestSuite) TestConcurrentDequeue() { + id := "test-id" + numCallbacks := 50 + var wg sync.WaitGroup + dequeued := make(chan bool, numCallbacks) + + // Queue callbacks + for i := 0; i < numCallbacks; i++ { + callback := func(confirmation ocpp.Response, err error) { + dequeued <- true + } + + try := func() error { + return nil + } + + err := suite.queue.TryQueue(id, try, callback) + suite.Require().NoError(err) + } + + // Concurrently dequeue callbacks + for i := 0; i < numCallbacks; i++ { + wg.Add(1) + go func() { + defer wg.Done() + cb, ok := suite.queue.Dequeue(id) + if ok && cb != nil { + cb(nil, nil) + } + }() + } + + wg.Wait() + + // Verify all callbacks were dequeued + suite.Assert().Len(dequeued, numCallbacks) + + // Queue should be empty + _, ok := suite.queue.Dequeue(id) + suite.Assert().False(ok) +} + +// TestDequeueWithError verifies that callbacks can be invoked with errors +func (suite *CallbackQueueTestSuite) TestDequeueWithError() { + id := "test-id" + var receivedError error + var receivedResponse ocpp.Response + + callback := func(confirmation ocpp.Response, err error) { + receivedResponse = confirmation + receivedError = err + } + + try := func() error { + return nil + } + + err := suite.queue.TryQueue(id, try, callback) + suite.Require().NoError(err) + + // Dequeue and invoke with error + ocppErr := ocpp.NewError(ocpp.ErrorCode("GenericError"), "test error", "123") + cb, ok := suite.queue.Dequeue(id) + suite.Require().True(ok) + cb(nil, ocppErr) + + suite.Assert().Nil(receivedResponse) + suite.Assert().NotNil(receivedError) + suite.Assert().Equal(ocppErr, receivedError) +} + +// TestDequeueWithResponse verifies that callbacks can be invoked with responses +func (suite *CallbackQueueTestSuite) TestDequeueWithResponse() { + id := "test-id" + var receivedError error + var receivedResponse ocpp.Response + + callback := func(confirmation ocpp.Response, err error) { + receivedResponse = confirmation + receivedError = err + } + + try := func() error { + return nil + } + + err := suite.queue.TryQueue(id, try, callback) + suite.Require().NoError(err) + + // Dequeue and invoke with response + mockResp := &MockResponse{Value: "success"} + cb, ok := suite.queue.Dequeue(id) + suite.Require().True(ok) + cb(mockResp, nil) + + suite.Assert().Equal(mockResp, receivedResponse) + suite.Assert().Nil(receivedError) +} + +// TestMultipleIDsConcurrent verifies concurrent operations on different IDs +func (suite *CallbackQueueTestSuite) TestMultipleIDsConcurrent() { + numIDs := 10 + callbacksPerID := 5 + var wg sync.WaitGroup + + // Queue callbacks for multiple IDs concurrently + for idIndex := 0; idIndex < numIDs; idIndex++ { + id := string(rune('a' + idIndex)) + for cbIndex := 0; cbIndex < callbacksPerID; cbIndex++ { + wg.Add(1) + go func(clientID string, callbackIndex int) { + defer wg.Done() + callback := func(confirmation ocpp.Response, err error) { + // Just verify it's called + } + + try := func() error { + return nil + } + + err := suite.queue.TryQueue(clientID, try, callback) + suite.Require().NoError(err) + }(id, cbIndex) + } + } + + wg.Wait() + + // Verify all callbacks were queued + for idIndex := 0; idIndex < numIDs; idIndex++ { + id := string(rune('a' + idIndex)) + dequeuedCount := 0 + for { + cb, ok := suite.queue.Dequeue(id) + if !ok { + break + } + cb(nil, nil) + dequeuedCount++ + } + suite.Assert().Equal(callbacksPerID, dequeuedCount, "All callbacks should be dequeued for ID %s", id) + } +} + +// TestDequeueEmptyIDAfterFailure verifies that ID is removed when last callback fails +func (suite *CallbackQueueTestSuite) TestDequeueEmptyIDAfterFailure() { + id := "test-id" + + callback := func(confirmation ocpp.Response, err error) {} + + tryFail := func() error { + return errors.New("failed") + } + + // Queue callback that fails + err := suite.queue.TryQueue(id, tryFail, callback) + suite.Require().Error(err) + + // ID should be removed from map + _, ok := suite.queue.Dequeue(id) + suite.Assert().False(ok) +} + +func TestCallbackQueue(t *testing.T) { + suite.Run(t, new(CallbackQueueTestSuite)) +} diff --git a/ocpp/ocpp.go b/ocpp/ocpp.go index 09019dd6..68a15d1e 100644 --- a/ocpp/ocpp.go +++ b/ocpp/ocpp.go @@ -62,12 +62,12 @@ func (err Error) Error() string { // This can easily be achieved by only registering certain profiles, while remaining compliant with the specifications. type Profile struct { Name string - Features map[string]Feature + features map[string]Feature } // Creates a new profile, identified by a name and a set of features. func NewProfile(name string, features ...Feature) *Profile { - profile := Profile{Name: name, Features: make(map[string]Feature)} + profile := Profile{Name: name, features: make(map[string]Feature)} for _, feature := range features { profile.AddFeature(feature) } @@ -76,25 +76,25 @@ func NewProfile(name string, features ...Feature) *Profile { // Adds a feature to the profile. func (p *Profile) AddFeature(feature Feature) { - p.Features[feature.GetFeatureName()] = feature + p.features[feature.GetFeatureName()] = feature } // SupportsFeature returns true if a feature matching the the passed name is registered with this profile, false otherwise. func (p *Profile) SupportsFeature(name string) bool { - _, ok := p.Features[name] + _, ok := p.features[name] return ok } // Retrieves a feature, identified by a unique name. // Returns nil in case the feature is not registered with this profile. func (p *Profile) GetFeature(name string) Feature { - return p.Features[name] + return p.features[name] } // ParseRequest checks whether a feature is supported and passes the rawRequest message to the requestParser function. // The type of the request message is passed to the requestParser function, which has to perform type assertion. func (p *Profile) ParseRequest(featureName string, rawRequest interface{}, requestParser func(raw interface{}, requestType reflect.Type) (Request, error)) (Request, error) { - feature, ok := p.Features[featureName] + feature, ok := p.features[featureName] if !ok { return nil, fmt.Errorf("Feature %s not found", featureName) } @@ -105,7 +105,7 @@ func (p *Profile) ParseRequest(featureName string, rawRequest interface{}, reque // ParseRequest checks whether a feature is supported and passes the rawResponse message to the responseParser function. // The type of the response message is passed to the responseParser function, which has to perform type assertion. func (p *Profile) ParseResponse(featureName string, rawResponse interface{}, responseParser func(raw interface{}, responseType reflect.Type) (Response, error)) (Response, error) { - feature, ok := p.Features[featureName] + feature, ok := p.features[featureName] if !ok { return nil, fmt.Errorf("Feature %s not found", featureName) } diff --git a/ocpp/ocpp_test.go b/ocpp/ocpp_test.go new file mode 100644 index 00000000..293dea21 --- /dev/null +++ b/ocpp/ocpp_test.go @@ -0,0 +1,743 @@ +package ocpp + +import ( + "fmt" + "reflect" + "testing" + + "github.com/stretchr/testify/suite" +) + +// Mock feature for testing +type TestFeature struct { + name string + requestType reflect.Type + responseType reflect.Type +} + +func (f *TestFeature) GetFeatureName() string { + return f.name +} + +func (f *TestFeature) GetRequestType() reflect.Type { + return f.requestType +} + +func (f *TestFeature) GetResponseType() reflect.Type { + return f.responseType +} + +// Mock request and response for testing ParseRequest and ParseResponse +type TestRequest struct { + Value string +} + +func (r *TestRequest) GetFeatureName() string { + return "TestFeature" +} + +type TestResponse struct { + Result int +} + +func (r *TestResponse) GetFeatureName() string { + return "TestFeature" +} + +type ProfileTestSuite struct { + suite.Suite +} + +func TestProfileSuite(t *testing.T) { + suite.Run(t, new(ProfileTestSuite)) +} + +func (suite *ProfileTestSuite) TestNewProfile_BasicCreation() { + tests := []struct { + name string + profileName string + features []Feature + expectedLength int + }{ + { + name: "empty name", + profileName: "", + features: nil, + expectedLength: 0, + }, + { + name: "with name, no features", + profileName: "test-profile", + features: nil, + expectedLength: 0, + }, + { + name: "empty profile name", + profileName: "empty-profile", + features: nil, + expectedLength: 0, + }, + } + + for _, tt := range tests { + suite.Run(tt.name, func() { + profile := NewProfile(tt.profileName, tt.features...) + suite.Assert().NotNil(profile) + suite.Assert().Equal(tt.profileName, profile.Name) + suite.Assert().NotNil(profile.features) + suite.Assert().Equal(tt.expectedLength, len(profile.features)) + suite.Assert().False(profile.SupportsFeature("nonexistent")) + }) + } +} + +func (suite *ProfileTestSuite) TestNewProfile_WithFeatures() { + tests := []struct { + name string + profileName string + features []*TestFeature + expectedLength int + expectedFeatures []struct { + name string + requestType reflect.Type + responseType reflect.Type + } + shouldNotExist []string + }{ + { + name: "single feature", + profileName: "single-feature-profile", + features: []*TestFeature{ + { + name: "TestFeature", + requestType: reflect.TypeOf(""), + responseType: reflect.TypeOf(0), + }, + }, + expectedLength: 1, + expectedFeatures: []struct { + name string + requestType reflect.Type + responseType reflect.Type + }{ + { + name: "TestFeature", + requestType: reflect.TypeOf(""), + responseType: reflect.TypeOf(0), + }, + }, + shouldNotExist: []string{"NonexistentFeature"}, + }, + { + name: "multiple features", + profileName: "multi-feature-profile", + features: []*TestFeature{ + { + name: "Feature1", + requestType: reflect.TypeOf(""), + responseType: reflect.TypeOf(0), + }, + { + name: "Feature2", + requestType: reflect.TypeOf(0), + responseType: reflect.TypeOf(""), + }, + { + name: "Feature3", + requestType: reflect.TypeOf(true), + responseType: reflect.TypeOf(1.0), + }, + }, + expectedLength: 3, + expectedFeatures: []struct { + name string + requestType reflect.Type + responseType reflect.Type + }{ + { + name: "Feature1", + requestType: reflect.TypeOf(""), + responseType: reflect.TypeOf(0), + }, + { + name: "Feature2", + requestType: reflect.TypeOf(0), + responseType: reflect.TypeOf(""), + }, + { + name: "Feature3", + requestType: reflect.TypeOf(true), + responseType: reflect.TypeOf(1.0), + }, + }, + shouldNotExist: []string{"NonexistentFeature"}, + }, + } + + for _, tt := range tests { + suite.Run(tt.name, func() { + // Convert []*TestFeature to []Feature + features := make([]Feature, len(tt.features)) + for i, f := range tt.features { + features[i] = f + } + + profile := NewProfile(tt.profileName, features...) + suite.Assert().NotNil(profile) + suite.Assert().Equal(tt.profileName, profile.Name) + suite.Assert().NotNil(profile.features) + suite.Assert().Equal(tt.expectedLength, len(profile.features)) + + // Verify expected features exist and are correct + for _, expected := range tt.expectedFeatures { + suite.Assert().True(profile.SupportsFeature(expected.name)) + retrievedFeature := profile.GetFeature(expected.name) + suite.Require().NotNil(retrievedFeature) + suite.Assert().Equal(expected.name, retrievedFeature.GetFeatureName()) + suite.Assert().Equal(expected.requestType, retrievedFeature.GetRequestType()) + suite.Assert().Equal(expected.responseType, retrievedFeature.GetResponseType()) + } + + // Verify features that should not exist + for _, name := range tt.shouldNotExist { + suite.Assert().False(profile.SupportsFeature(name)) + suite.Assert().Nil(profile.GetFeature(name)) + } + }) + } +} + +func (suite *ProfileTestSuite) TestNewProfile_DuplicateFeatures() { + tests := []struct { + name string + profileName string + features []*TestFeature + expectedLength int + expectedFeature struct { + name string + requestType reflect.Type + responseType reflect.Type + } + }{ + { + name: "duplicate features overwrite", + profileName: "duplicate-feature-profile", + features: []*TestFeature{ + { + name: "DuplicateFeature", + requestType: reflect.TypeOf(""), + responseType: reflect.TypeOf(0), + }, + { + name: "DuplicateFeature", + requestType: reflect.TypeOf(0), + responseType: reflect.TypeOf(""), + }, + }, + expectedLength: 1, + expectedFeature: struct { + name string + requestType reflect.Type + responseType reflect.Type + }{ + name: "DuplicateFeature", + requestType: reflect.TypeOf(0), + responseType: reflect.TypeOf(""), + }, + }, + } + + for _, tt := range tests { + suite.Run(tt.name, func() { + // Convert []*TestFeature to []Feature + features := make([]Feature, len(tt.features)) + for i, f := range tt.features { + features[i] = f + } + + // When duplicate features are added, the last one should overwrite the previous one + profile := NewProfile(tt.profileName, features...) + suite.Assert().NotNil(profile) + suite.Assert().Equal(tt.profileName, profile.Name) + suite.Assert().NotNil(profile.features) + suite.Assert().Equal(tt.expectedLength, len(profile.features)) + + retrievedFeature := profile.GetFeature(tt.expectedFeature.name) + suite.Require().NotNil(retrievedFeature) + // Should be the last feature added (overwrites previous) + suite.Assert().Equal(tt.expectedFeature.requestType, retrievedFeature.GetRequestType()) + suite.Assert().Equal(tt.expectedFeature.responseType, retrievedFeature.GetResponseType()) + }) + } +} + +func (suite *ProfileTestSuite) TestProfile_AddFeature() { + tests := []struct { + name string + profileName string + initialFeatures []*TestFeature + featuresToAdd []*TestFeature + expectedLength int + expectedFeatures []string + }{ + { + name: "add to empty profile", + profileName: "test-profile", + initialFeatures: nil, + featuresToAdd: []*TestFeature{ + { + name: "Feature1", + requestType: reflect.TypeOf(""), + responseType: reflect.TypeOf(0), + }, + }, + expectedLength: 1, + expectedFeatures: []string{"Feature1"}, + }, + { + name: "add multiple features", + profileName: "test-profile", + initialFeatures: []*TestFeature{ + { + name: "ExistingFeature", + requestType: reflect.TypeOf(""), + responseType: reflect.TypeOf(0), + }, + }, + featuresToAdd: []*TestFeature{ + { + name: "NewFeature1", + requestType: reflect.TypeOf(0), + responseType: reflect.TypeOf(""), + }, + { + name: "NewFeature2", + requestType: reflect.TypeOf(true), + responseType: reflect.TypeOf(1.0), + }, + }, + expectedLength: 3, + expectedFeatures: []string{"ExistingFeature", "NewFeature1", "NewFeature2"}, + }, + { + name: "overwrite existing feature", + profileName: "test-profile", + initialFeatures: []*TestFeature{ + { + name: "Feature1", + requestType: reflect.TypeOf(""), + responseType: reflect.TypeOf(0), + }, + }, + featuresToAdd: []*TestFeature{ + { + name: "Feature1", + requestType: reflect.TypeOf(0), + responseType: reflect.TypeOf(""), + }, + }, + expectedLength: 1, + expectedFeatures: []string{"Feature1"}, + }, + } + + for _, tt := range tests { + suite.Run(tt.name, func() { + // Create profile with initial features + initialFeatures := make([]Feature, len(tt.initialFeatures)) + for i, f := range tt.initialFeatures { + initialFeatures[i] = f + } + profile := NewProfile(tt.profileName, initialFeatures...) + + // Add new features + for _, feature := range tt.featuresToAdd { + profile.AddFeature(feature) + } + + suite.Assert().Equal(tt.expectedLength, len(profile.features)) + for _, expectedName := range tt.expectedFeatures { + suite.Assert().True(profile.SupportsFeature(expectedName)) + } + + // Verify last added feature overwrites if duplicate + if len(tt.featuresToAdd) > 0 { + lastFeature := tt.featuresToAdd[len(tt.featuresToAdd)-1] + retrieved := profile.GetFeature(lastFeature.name) + suite.Require().NotNil(retrieved) + suite.Assert().Equal(lastFeature.requestType, retrieved.GetRequestType()) + } + }) + } +} + +func (suite *ProfileTestSuite) TestProfile_SupportsFeature() { + tests := []struct { + name string + profileName string + features []*TestFeature + featureToCheck string + expectedSupport bool + }{ + { + name: "feature exists", + profileName: "test-profile", + features: []*TestFeature{ + { + name: "Feature1", + requestType: reflect.TypeOf(""), + responseType: reflect.TypeOf(0), + }, + }, + featureToCheck: "Feature1", + expectedSupport: true, + }, + { + name: "feature does not exist", + profileName: "test-profile", + features: []*TestFeature{ + { + name: "Feature1", + requestType: reflect.TypeOf(""), + responseType: reflect.TypeOf(0), + }, + }, + featureToCheck: "NonexistentFeature", + expectedSupport: false, + }, + { + name: "empty profile", + profileName: "test-profile", + features: nil, + featureToCheck: "AnyFeature", + expectedSupport: false, + }, + { + name: "case sensitive check", + profileName: "test-profile", + features: []*TestFeature{ + { + name: "Feature1", + requestType: reflect.TypeOf(""), + responseType: reflect.TypeOf(0), + }, + }, + featureToCheck: "feature1", + expectedSupport: false, + }, + } + + for _, tt := range tests { + suite.Run(tt.name, func() { + features := make([]Feature, len(tt.features)) + for i, f := range tt.features { + features[i] = f + } + profile := NewProfile(tt.profileName, features...) + suite.Assert().Equal(tt.expectedSupport, profile.SupportsFeature(tt.featureToCheck)) + }) + } +} + +func (suite *ProfileTestSuite) TestProfile_GetFeature() { + tests := []struct { + name string + profileName string + features []*TestFeature + featureToGet string + expectedFeature *TestFeature + shouldBeNil bool + }{ + { + name: "get existing feature", + profileName: "test-profile", + features: []*TestFeature{ + { + name: "Feature1", + requestType: reflect.TypeOf(""), + responseType: reflect.TypeOf(0), + }, + }, + featureToGet: "Feature1", + expectedFeature: &TestFeature{ + name: "Feature1", + requestType: reflect.TypeOf(""), + responseType: reflect.TypeOf(0), + }, + shouldBeNil: false, + }, + { + name: "get nonexistent feature", + profileName: "test-profile", + features: []*TestFeature{ + { + name: "Feature1", + requestType: reflect.TypeOf(""), + responseType: reflect.TypeOf(0), + }, + }, + featureToGet: "NonexistentFeature", + expectedFeature: nil, + shouldBeNil: true, + }, + { + name: "get from empty profile", + profileName: "test-profile", + features: nil, + featureToGet: "AnyFeature", + expectedFeature: nil, + shouldBeNil: true, + }, + { + name: "get from multiple features", + profileName: "test-profile", + features: []*TestFeature{ + { + name: "Feature1", + requestType: reflect.TypeOf(""), + responseType: reflect.TypeOf(0), + }, + { + name: "Feature2", + requestType: reflect.TypeOf(0), + responseType: reflect.TypeOf(""), + }, + }, + featureToGet: "Feature2", + expectedFeature: &TestFeature{ + name: "Feature2", + requestType: reflect.TypeOf(0), + responseType: reflect.TypeOf(""), + }, + shouldBeNil: false, + }, + } + + for _, tt := range tests { + suite.Run(tt.name, func() { + features := make([]Feature, len(tt.features)) + for i, f := range tt.features { + features[i] = f + } + profile := NewProfile(tt.profileName, features...) + retrieved := profile.GetFeature(tt.featureToGet) + + if tt.shouldBeNil { + suite.Assert().Nil(retrieved) + } else { + suite.Require().NotNil(retrieved) + suite.Assert().Equal(tt.expectedFeature.name, retrieved.GetFeatureName()) + suite.Assert().Equal(tt.expectedFeature.requestType, retrieved.GetRequestType()) + suite.Assert().Equal(tt.expectedFeature.responseType, retrieved.GetResponseType()) + } + }) + } +} + +func (suite *ProfileTestSuite) TestProfile_ParseRequest() { + tests := []struct { + name string + profileName string + features []*TestFeature + featureName string + rawRequest interface{} + requestParser func(raw interface{}, requestType reflect.Type) (Request, error) + expectedRequest Request + expectedError string + }{ + { + name: "successful parse", + profileName: "test-profile", + features: []*TestFeature{ + { + name: "TestFeature", + requestType: reflect.TypeOf(&TestRequest{}), + responseType: reflect.TypeOf(&TestResponse{}), + }, + }, + featureName: "TestFeature", + rawRequest: map[string]interface{}{"Value": "test"}, + requestParser: func(raw interface{}, requestType reflect.Type) (Request, error) { + suite.Assert().Equal(reflect.TypeOf(&TestRequest{}), requestType) + return &TestRequest{Value: "test"}, nil + }, + expectedRequest: &TestRequest{Value: "test"}, + expectedError: "", + }, + { + name: "feature not found", + profileName: "test-profile", + features: []*TestFeature{ + { + name: "OtherFeature", + requestType: reflect.TypeOf(&TestRequest{}), + responseType: reflect.TypeOf(&TestResponse{}), + }, + }, + featureName: "NonexistentFeature", + rawRequest: map[string]interface{}{"Value": "test"}, + requestParser: func(raw interface{}, requestType reflect.Type) (Request, error) { + return nil, nil + }, + expectedRequest: nil, + expectedError: "Feature NonexistentFeature not found", + }, + { + name: "empty profile", + profileName: "test-profile", + features: nil, + featureName: "AnyFeature", + rawRequest: map[string]interface{}{"Value": "test"}, + requestParser: func(raw interface{}, requestType reflect.Type) (Request, error) { + return nil, nil + }, + expectedRequest: nil, + expectedError: "Feature AnyFeature not found", + }, + { + name: "parser returns error", + profileName: "test-profile", + features: []*TestFeature{ + { + name: "TestFeature", + requestType: reflect.TypeOf(&TestRequest{}), + responseType: reflect.TypeOf(&TestResponse{}), + }, + }, + featureName: "TestFeature", + rawRequest: map[string]interface{}{"Value": "test"}, + requestParser: func(raw interface{}, requestType reflect.Type) (Request, error) { + return nil, fmt.Errorf("parse error") + }, + expectedRequest: nil, + expectedError: "parse error", + }, + } + + for _, tt := range tests { + suite.Run(tt.name, func() { + features := make([]Feature, len(tt.features)) + for i, f := range tt.features { + features[i] = f + } + profile := NewProfile(tt.profileName, features...) + request, err := profile.ParseRequest(tt.featureName, tt.rawRequest, tt.requestParser) + + if tt.expectedError != "" { + suite.Require().Error(err) + suite.Assert().Contains(err.Error(), tt.expectedError) + suite.Assert().Nil(request) + } else { + suite.Require().NoError(err) + suite.Assert().NotNil(request) + if tt.expectedRequest != nil { + suite.Assert().Equal(tt.expectedRequest.GetFeatureName(), request.GetFeatureName()) + } + } + }) + } +} + +func (suite *ProfileTestSuite) TestProfile_ParseResponse() { + tests := []struct { + name string + profileName string + features []*TestFeature + featureName string + rawResponse interface{} + responseParser func(raw interface{}, responseType reflect.Type) (Response, error) + expectedResponse Response + expectedError string + }{ + { + name: "successful parse", + profileName: "test-profile", + features: []*TestFeature{ + { + name: "TestFeature", + requestType: reflect.TypeOf(&TestRequest{}), + responseType: reflect.TypeOf(&TestResponse{}), + }, + }, + featureName: "TestFeature", + rawResponse: map[string]interface{}{"Result": 42}, + responseParser: func(raw interface{}, responseType reflect.Type) (Response, error) { + suite.Assert().Equal(reflect.TypeOf(&TestResponse{}), responseType) + return &TestResponse{Result: 42}, nil + }, + expectedResponse: &TestResponse{Result: 42}, + expectedError: "", + }, + { + name: "feature not found", + profileName: "test-profile", + features: []*TestFeature{ + { + name: "OtherFeature", + requestType: reflect.TypeOf(&TestRequest{}), + responseType: reflect.TypeOf(&TestResponse{}), + }, + }, + featureName: "NonexistentFeature", + rawResponse: map[string]interface{}{"Result": 42}, + responseParser: func(raw interface{}, responseType reflect.Type) (Response, error) { + return nil, nil + }, + expectedResponse: nil, + expectedError: "Feature NonexistentFeature not found", + }, + { + name: "empty profile", + profileName: "test-profile", + features: nil, + featureName: "AnyFeature", + rawResponse: map[string]interface{}{"Result": 42}, + responseParser: func(raw interface{}, responseType reflect.Type) (Response, error) { + return nil, nil + }, + expectedResponse: nil, + expectedError: "Feature AnyFeature not found", + }, + { + name: "parser returns error", + profileName: "test-profile", + features: []*TestFeature{ + { + name: "TestFeature", + requestType: reflect.TypeOf(&TestRequest{}), + responseType: reflect.TypeOf(&TestResponse{}), + }, + }, + featureName: "TestFeature", + rawResponse: map[string]interface{}{"Result": 42}, + responseParser: func(raw interface{}, responseType reflect.Type) (Response, error) { + return nil, fmt.Errorf("parse error") + }, + expectedResponse: nil, + expectedError: "parse error", + }, + } + + for _, tt := range tests { + suite.Run(tt.name, func() { + features := make([]Feature, len(tt.features)) + for i, f := range tt.features { + features[i] = f + } + profile := NewProfile(tt.profileName, features...) + response, err := profile.ParseResponse(tt.featureName, tt.rawResponse, tt.responseParser) + + if tt.expectedError != "" { + suite.Require().Error(err) + suite.Assert().Contains(err.Error(), tt.expectedError) + suite.Assert().Nil(response) + } else { + suite.Require().NoError(err) + suite.Assert().NotNil(response) + if tt.expectedResponse != nil { + suite.Assert().Equal(tt.expectedResponse.GetFeatureName(), response.GetFeatureName()) + } + } + }) + } +} diff --git a/ocpp1.6/central_system.go b/ocpp1.6/central_system.go index 6dbfac4a..3fb7ff9f 100644 --- a/ocpp1.6/central_system.go +++ b/ocpp1.6/central_system.go @@ -1,25 +1,26 @@ package ocpp16 import ( + "errors" "fmt" "reflect" - "github.com/lorenzodonini/ocpp-go/internal/callbackqueue" - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/certificates" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/extendedtriggermessage" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/logging" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/remotetrigger" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/securefirmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/security" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/lorenzodonini/ocpp-go/ocppj" - "github.com/lorenzodonini/ocpp-go/ws" + "github.com/xBlaz3kx/ocpp-go/internal/callbackqueue" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/certificates" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/extendedtriggermessage" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/logging" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/remotetrigger" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/securefirmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/security" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ws" ) type centralSystem struct { @@ -37,15 +38,16 @@ type centralSystem struct { errC chan error } -func newCentralSystem(server *ocppj.Server) centralSystem { +func newCentralSystem(server *ocppj.Server) (centralSystem, error) { if server == nil { - panic("server must not be nil") + return centralSystem{}, errors.New("server must not be nil") } + server.SetDialect(ocpp.V16) return centralSystem{ server: server, callbackQueue: callbackqueue.New(), - } + }, nil } func (cs *centralSystem) error(err error) { diff --git a/ocpp1.6/certificates/certificates.go b/ocpp1.6/certificates/certificates.go index 3ed15bf8..f0636020 100644 --- a/ocpp1.6/certificates/certificates.go +++ b/ocpp1.6/certificates/certificates.go @@ -1,7 +1,7 @@ // The diagnostics functional block contains OCPP 2.0 features than enable remote diagnostics of problems with a charging station. package certificates -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by Charging stations for handling messages part of the OCPP 1.6j security extension. type ChargePointHandler interface { diff --git a/ocpp1.6/certificates/delete_certificate.go b/ocpp1.6/certificates/delete_certificate.go index 25f6c5c8..0b3d8785 100644 --- a/ocpp1.6/certificates/delete_certificate.go +++ b/ocpp1.6/certificates/delete_certificate.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // -------------------- Delete Certificate (CSMS -> CS) -------------------- diff --git a/ocpp1.6/certificates/get_installed_certificates.go b/ocpp1.6/certificates/get_installed_certificates.go index fd494a2f..74ccad04 100644 --- a/ocpp1.6/certificates/get_installed_certificates.go +++ b/ocpp1.6/certificates/get_installed_certificates.go @@ -3,7 +3,7 @@ package certificates import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp1.6/certificates/install_certificate.go b/ocpp1.6/certificates/install_certificate.go index 9f972827..20a1a54d 100644 --- a/ocpp1.6/certificates/install_certificate.go +++ b/ocpp1.6/certificates/install_certificate.go @@ -3,7 +3,7 @@ package certificates import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp1.6/charge_point.go b/ocpp1.6/charge_point.go index 37cd0180..f17895dd 100644 --- a/ocpp1.6/charge_point.go +++ b/ocpp1.6/charge_point.go @@ -4,21 +4,21 @@ import ( "fmt" "reflect" - "github.com/lorenzodonini/ocpp-go/internal/callbackqueue" - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/certificates" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/extendedtriggermessage" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/logging" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/remotetrigger" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/securefirmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/security" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/lorenzodonini/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/internal/callbackqueue" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/certificates" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/extendedtriggermessage" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/logging" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/remotetrigger" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/securefirmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/security" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocppj" ) type chargePoint struct { diff --git a/ocpp1.6/config_manager/configuration.go b/ocpp1.6/config_manager/configuration.go new file mode 100644 index 00000000..e75c6c46 --- /dev/null +++ b/ocpp1.6/config_manager/configuration.go @@ -0,0 +1,110 @@ +package ocpp_16_config_manager + +import ( + "errors" + "fmt" + "strings" + + "github.com/samber/lo" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" +) + +var ( + ErrKeyNotFound = errors.New("key not found") + ErrReadOnly = errors.New("attribute is read-only") +) + +type Key string + +func (k Key) String() string { + return string(k) +} + +type Config struct { + Version int `fig:"version" default:"1"` + Keys []core.ConfigurationKey `fig:"keys"` +} + +// UpdateKey Update the configuration variable in the configuration if it is not readonly. +func (config *Config) UpdateKey(key string, value *string) error { + // Find the index of the key + configKey, index, isFound := lo.FindIndexOf(config.Keys, func(item core.ConfigurationKey) bool { + return item.Key == key + }) + if !isFound { + return ErrKeyNotFound + } + + if configKey.Readonly { + return ErrReadOnly + } + + config.Keys[index].Value = value + return nil +} + +// UpdateKeyReadability updates whether the key is updatable or not. +func (config *Config) UpdateKeyReadability(key string, readable bool) error { + // Find the index of the key + _, index, isFound := lo.FindIndexOf(config.Keys, func(item core.ConfigurationKey) bool { + return item.Key == key + }) + if !isFound { + return ErrKeyNotFound + } + + config.Keys[index].Readonly = readable + return nil +} + +// GetConfigurationValue Get the value of specified configuration variable in String format. +func (config *Config) GetConfigurationValue(key string) (*string, error) { + configKey, isFound := lo.Find(config.Keys, func(item core.ConfigurationKey) bool { + return item.Key == key + }) + + if !isFound { + return nil, ErrKeyNotFound + } + + return configKey.Value, nil +} + +// GetConfig Get the configuration +func (config *Config) GetConfig() []core.ConfigurationKey { + return config.Keys +} + +// GetVersion Get the current version +func (config *Config) GetVersion() int { + return config.Version +} + +// SetVersion Set the current version +func (config *Config) SetVersion(version int) { + config.Version = version +} + +// Validate validates the configuration - check if all mandatory keys are present. +func (config *Config) Validate(mandatoryKeys []Key) error { + missingKeys := "" + + containsMandatoryKeys := true + + for _, key := range mandatoryKeys { + containsKey := lo.ContainsBy(config.Keys, func(item core.ConfigurationKey) bool { + return item.Key == key.String() + }) + + if !containsKey { + missingKeys = strings.Join([]string{missingKeys, key.String()}, ", ") + containsMandatoryKeys = false + } + } + + if !containsMandatoryKeys { + return fmt.Errorf("missing mandatory keys: %s", missingKeys) + } + + return nil +} diff --git a/ocpp1.6/config_manager/configuration_test.go b/ocpp1.6/config_manager/configuration_test.go new file mode 100644 index 00000000..5ddc7f8b --- /dev/null +++ b/ocpp1.6/config_manager/configuration_test.go @@ -0,0 +1,151 @@ +package ocpp_16_config_manager + +import ( + "testing" + + "github.com/samber/lo" + "github.com/stretchr/testify/suite" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" +) + +var ( + val1 = "60" + val2 = "ABCD" +) + +type OcppConfigTest struct { + suite.Suite + config Config +} + +func (s *OcppConfigTest) SetupTest() { + s.config = Config{ + Version: 1, + Keys: []core.ConfigurationKey{ + { + Key: "HeartbeatInterval", + Readonly: false, + Value: &val1, + }, { + Key: "ChargingScheduleAllowedChargingRateUnit", + Readonly: true, + Value: &val2, + }, { + Key: "AuthorizationCacheEnabled", + Readonly: false, + Value: nil, + }, + }, + } +} + +func (s *OcppConfigTest) TestGetConfig() { + s.Assert().Equal([]core.ConfigurationKey{ + { + Key: "HeartbeatInterval", + Readonly: false, + Value: &val1, + }, { + Key: "ChargingScheduleAllowedChargingRateUnit", + Readonly: true, + Value: &val2, + }, { + Key: "AuthorizationCacheEnabled", + Readonly: false, + Value: nil, + }, + }, s.config.GetConfig()) + + // Overwrite the config + s.config = Config{ + Version: 1, + Keys: []core.ConfigurationKey{}, + } + + s.Assert().Equal([]core.ConfigurationKey{}, s.config.GetConfig()) +} + +func (s *OcppConfigTest) TestGetConfigurationValue() { + // Ok case + value, err := s.config.GetConfigurationValue(HeartbeatInterval.String()) + s.Require().NoError(err) + s.Assert().EqualValues("60", *value) + + // Invalid key + value, err = s.config.GetConfigurationValue("Test4") + s.Assert().Error(err) + s.Assert().Nil(value) +} + +func (s *OcppConfigTest) TestGetVersion() { + s.Assert().EqualValues(1, s.config.GetVersion()) + + s.config.Version = 1234 + + s.Assert().EqualValues(1234, s.config.GetVersion()) +} + +func (s *OcppConfigTest) TestSetVersion() { + s.config.SetVersion(1234) + s.Assert().EqualValues(1234, s.config.Version) + + s.config.SetVersion(1) + s.Assert().EqualValues(1, s.config.Version) +} + +func (s *OcppConfigTest) TestUpdateKey() { + // Ok case + newVal := "1234" + err := s.config.UpdateKey("HeartbeatInterval", &newVal) + s.Assert().NoError(err) + value, err := s.config.GetConfigurationValue("HeartbeatInterval") + s.Require().NoError(err) + s.Assert().EqualValues("1234", *value) + + // Invalid key + err = s.config.UpdateKey("Test4", nil) + s.Assert().Error(err) + + // Key cannot be updated + err = s.config.UpdateKey("ChargingScheduleAllowedChargingRateUnit", nil) + s.Assert().Error(err) + + // Check if the value was not updated + value, err = s.config.GetConfigurationValue("ChargingScheduleAllowedChargingRateUnit") + s.Assert().NoError(err) + s.Assert().EqualValues("ABCD", *value) +} + +func (s *OcppConfigTest) TestUpdateKeyReadability() { + // Ok case + err := s.config.UpdateKeyReadability(HeartbeatInterval.String(), true) + s.Assert().NoError(err) + + configKey, isFound := lo.Find(s.config.Keys, func(item core.ConfigurationKey) bool { + return item.Key == HeartbeatInterval.String() + }) + s.Assert().True(isFound) + s.Assert().EqualValues(true, configKey.Readonly) + + // Invalid key + err = s.config.UpdateKeyReadability("Test4", true) + s.Assert().Error(err) +} + +func (s *OcppConfigTest) TestValidate() { + s.config = NewEmptyConfiguration() + s.config.Keys = DefaultCoreConfiguration() + + // Ok case + err := s.config.Validate(MandatoryCoreKeys) + s.Assert().NoError(err) + + // Missing mandatory key + s.config.Keys = s.config.Keys[:len(s.config.Keys)-2] + err = s.config.Validate(MandatoryCoreKeys) + s.Assert().Error(err) +} + +func TestOCPPConfig(t *testing.T) { + suite.Run(t, new(OcppConfigTest)) +} diff --git a/ocpp1.6/config_manager/defaults.go b/ocpp1.6/config_manager/defaults.go new file mode 100644 index 00000000..9d7ee0ab --- /dev/null +++ b/ocpp1.6/config_manager/defaults.go @@ -0,0 +1,226 @@ +package ocpp_16_config_manager + +import ( + "fmt" + "strings" + + "github.com/samber/lo" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" +) + +func NewEmptyConfiguration() Config { + return Config{ + Version: 1, + Keys: []core.ConfigurationKey{}, + } +} + +func DefaultConfigurationFromProfiles(profiles ...string) (*Config, error) { + keys := []core.ConfigurationKey{} + + if len(profiles) == 0 { + return nil, fmt.Errorf("no profiles provided") + } + + for _, profile := range profiles { + switch profile { + case core.ProfileName: + keys = append(keys, DefaultCoreConfiguration()...) + case localauth.ProfileName: + keys = append(keys, DefaultLocalAuthConfiguration()...) + case smartcharging.ProfileName: + keys = append(keys, DefaultSmartChargingConfiguration()...) + case firmware.ProfileName: + keys = append(keys, DefaultFirmwareConfiguration()...) + default: + return nil, fmt.Errorf("unknown profile %v", profile) + } + } + + return &Config{ + Version: 1, + Keys: keys, + }, nil +} + +func DefaultCoreConfiguration() []core.ConfigurationKey { + return []core.ConfigurationKey{ + { + Key: AuthorizeRemoteTxRequests.String(), + Readonly: false, + Value: lo.ToPtr("true"), + }, + { + Key: ClockAlignedDataInterval.String(), + Readonly: false, + Value: lo.ToPtr("0"), + }, + { + Key: ConnectionTimeOut.String(), + Readonly: false, + Value: lo.ToPtr("60"), + }, + { + Key: GetConfigurationMaxKeys.String(), + Readonly: false, + Value: lo.ToPtr("100"), + }, + { + Key: HeartbeatInterval.String(), + Readonly: false, + Value: lo.ToPtr("60"), + }, + { + Key: LocalPreAuthorize.String(), + Readonly: false, + Value: lo.ToPtr("false"), + }, + { + Key: MeterValuesAlignedData.String(), + Readonly: false, + Value: lo.ToPtr("true"), + }, + { + Key: MeterValuesSampledData.String(), + Readonly: false, + Value: lo.ToPtr(strings.Join([]string{ + string(types.MeasurandVoltage), + string(types.MeasurandCurrentImport), + string(types.MeasurandPowerActiveImport), + string(types.MeasurandEnergyActiveImportInterval), + string(types.MeasurandSoC), + }, ",")), + }, + { + Key: MeterValueSampleInterval.String(), + Readonly: false, + Value: lo.ToPtr("20"), + }, + { + Key: NumberOfConnectors.String(), + Readonly: true, + Value: lo.ToPtr("1"), + }, + { + Key: ResetRetries.String(), + Readonly: false, + Value: lo.ToPtr("3"), + }, + { + Key: ConnectorPhaseRotation.String(), + Readonly: true, + Value: lo.ToPtr("Unknown"), + }, + { + Key: StopTransactionOnEVSideDisconnect.String(), + Readonly: false, + Value: lo.ToPtr("true"), + }, + { + Key: StopTransactionOnInvalidId.String(), + Readonly: false, + Value: lo.ToPtr("true"), + }, + { + Key: StopTxnAlignedData.String(), + Readonly: false, + Value: lo.ToPtr(strings.Join([]string{ + string(types.MeasurandVoltage), + string(types.MeasurandCurrentImport), + string(types.MeasurandPowerActiveImport), + string(types.MeasurandEnergyActiveImportInterval), + string(types.MeasurandSoC), + }, ",")), + }, + { + Key: StopTxnSampledData.String(), + Readonly: false, + Value: lo.ToPtr(strings.Join([]string{ + string(types.MeasurandVoltage), + string(types.MeasurandCurrentImport), + string(types.MeasurandPowerActiveImport), + string(types.MeasurandEnergyActiveImportInterval), + string(types.MeasurandSoC), + }, ",")), + }, + { + Key: SupportedFeatureProfiles.String(), + Readonly: true, + Value: lo.ToPtr("Core"), + }, + { + Key: TransactionMessageAttempts.String(), + Readonly: false, + Value: lo.ToPtr("3"), + }, + { + Key: TransactionMessageRetryInterval.String(), + Readonly: false, + Value: lo.ToPtr("30"), + }, + { + Key: UnlockConnectorOnEVSideDisconnect.String(), + Readonly: false, + Value: lo.ToPtr("true"), + }, + } +} + +func DefaultLocalAuthConfiguration() []core.ConfigurationKey { + return []core.ConfigurationKey{ + { + Key: LocalAuthListEnabled.String(), + Readonly: false, + Value: lo.ToPtr("true"), + }, + { + Key: LocalAuthListMaxLength.String(), + Readonly: true, + Value: lo.ToPtr("100"), + }, + { + Key: SendLocalListMaxLength.String(), + Readonly: true, + Value: lo.ToPtr("100"), + }, + } +} + +func DefaultSmartChargingConfiguration() []core.ConfigurationKey { + return []core.ConfigurationKey{ + { + Key: ChargeProfileMaxStackLevel.String(), + Readonly: true, + Value: lo.ToPtr("5"), + }, + { + Key: ChargingScheduleAllowedChargingRateUnit.String(), + Readonly: true, + Value: lo.ToPtr("Current,Power"), + }, + { + Key: ChargingScheduleMaxPeriods.String(), + Readonly: true, + Value: lo.ToPtr("6"), + }, + { + Key: MaxChargingProfilesInstalled.String(), + Readonly: true, + Value: lo.ToPtr("5"), + }, + } +} + +func DefaultFirmwareConfiguration() []core.ConfigurationKey { + return []core.ConfigurationKey{ + { + Key: SupportedFileTransferProtocols.String(), + Readonly: true, + Value: lo.ToPtr("HTTP,HTTPS,FTP,FTPS,SFTP"), + }, + } +} diff --git a/ocpp1.6/config_manager/defaults_test.go b/ocpp1.6/config_manager/defaults_test.go new file mode 100644 index 00000000..60f589e4 --- /dev/null +++ b/ocpp1.6/config_manager/defaults_test.go @@ -0,0 +1,66 @@ +package ocpp_16_config_manager + +import ( + "testing" + + "github.com/stretchr/testify/suite" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" +) + +type defaultsTestSuite struct { + suite.Suite +} + +func (suite *defaultsTestSuite) TestNewEmptyConfiguration() { + config := NewEmptyConfiguration() + suite.Equal(1, config.Version) + suite.Empty(config.Keys) +} + +func (suite *defaultsTestSuite) TestDefaultConfiguration() { + + // Default configuration with core, localauth and smartcharging profiles + keys := append(DefaultCoreConfiguration(), DefaultLocalAuthConfiguration()...) + keys = append(keys, DefaultSmartChargingConfiguration()...) + + config, err := DefaultConfigurationFromProfiles(core.ProfileName, localauth.ProfileName, smartcharging.ProfileName) + suite.NoError(err) + suite.Equal(1, config.Version) + suite.NotEmpty(config.Keys) + suite.ElementsMatch(keys, config.Keys) + + // Default configuration with unknown profile + config, err = DefaultConfigurationFromProfiles(core.ProfileName, localauth.ProfileName, smartcharging.ProfileName, "unknown") + suite.Error(err) + suite.Nil(config) + + config, err = DefaultConfigurationFromProfiles() + suite.Error(err) + suite.Nil(config) +} + +func (suite *defaultsTestSuite) TestDefaultCoreConfiguration() { + config := DefaultCoreConfiguration() + suite.NotEmpty(config) +} + +func (suite *defaultsTestSuite) TestDefaultLocalAuthConfiguration() { + config := DefaultLocalAuthConfiguration() + suite.NotEmpty(config) +} + +func (suite *defaultsTestSuite) TestDefaultSmartChargingConfiguration() { + config := DefaultSmartChargingConfiguration() + suite.NotEmpty(config) +} + +func (suite *defaultsTestSuite) TestDefaultFirmwareConfiguration() { + config := DefaultFirmwareConfiguration() + suite.NotEmpty(config) +} + +func TestDefaultConfigurations(t *testing.T) { + suite.Run(t, new(defaultsTestSuite)) +} diff --git a/ocpp1.6/config_manager/keys.go b/ocpp1.6/config_manager/keys.go new file mode 100644 index 00000000..6235ca80 --- /dev/null +++ b/ocpp1.6/config_manager/keys.go @@ -0,0 +1,153 @@ +package ocpp_16_config_manager + +import ( + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" +) + +const ( + /* ----------------- Core keys ----------------------- */ + + AllowOfflineTxForUnknownId = Key("AllowOfflineTxForUnknownId") + AuthorizationCacheEnabled = Key("AuthorizationCacheEnabled") + AuthorizeRemoteTxRequests = Key("AuthorizeRemoteTxRequests") + BlinkRepeat = Key("BlinkRepeat") + ClockAlignedDataInterval = Key("ClockAlignedDataInterval") + ConnectionTimeOut = Key("ConnectionTimeOut") + GetConfigurationMaxKeys = Key("GetConfigurationMaxKeys") + HeartbeatInterval = Key("HeartbeatInterval") + LightIntensity = Key("LightIntensity") + LocalAuthorizeOffline = Key("LocalAuthorizeOffline") + LocalPreAuthorize = Key("LocalPreAuthorize") + MaxEnergyOnInvalidId = Key("MaxEnergyOnInvalidId") + MeterValuesAlignedData = Key("MeterValuesAlignedData") + MeterValuesAlignedDataMaxLength = Key("MeterValuesAlignedDataMaxLength") + MeterValuesSampledData = Key("MeterValuesSampledData") + MeterValuesSampledDataMaxLength = Key("MeterValuesSampledDataMaxLength") + MeterValueSampleInterval = Key("MeterValueSampleInterval") + MinimumStatusDuration = Key("MinimumStatusDuration") + NumberOfConnectors = Key("NumberOfConnectors") + ResetRetries = Key("ResetRetries") + ConnectorPhaseRotation = Key("ConnectorPhaseRotation") + ConnectorPhaseRotationMaxLength = Key("ConnectorPhaseRotationMaxLength") + StopTransactionOnEVSideDisconnect = Key("StopTransactionOnEVSideDisconnect") + StopTransactionOnInvalidId = Key("StopTransactionOnInvalidId") + StopTxnAlignedData = Key("StopTxnAlignedData") + StopTxnAlignedDataMaxLength = Key("StopTxnAlignedDataMaxLength") + StopTxnSampledData = Key("StopTxnSampledData") + StopTxnSampledDataMaxLength = Key("StopTxnSampledDataMaxLength") + SupportedFeatureProfiles = Key("SupportedFeatureProfiles") + SupportedFeatureProfilesMaxLength = Key("SupportedFeatureProfilesMaxLength") + TransactionMessageAttempts = Key("TransactionMessageAttempts") + TransactionMessageRetryInterval = Key("TransactionMessageRetryInterval") + UnlockConnectorOnEVSideDisconnect = Key("UnlockConnectorOnEVSideDisconnect") + WebSocketPingInterval = Key("WebSocketPingInterval") + + /* ----------------- LocalAuthList keys ----------------------- */ + + LocalAuthListEnabled = Key("LocalAuthListEnabled") + LocalAuthListMaxLength = Key("LocalAuthListMaxLength") + SendLocalListMaxLength = Key("SendLocalListMaxLength") + + /* ----------------- Reservation keys ----------------------- */ + + ReserveConnectorZeroSupported = Key("ReserveConnectorZeroSupported") + + /* ----------------- Firmware keys ----------------------- */ + + SupportedFileTransferProtocols = Key("SupportedFileTransferProtocols") + + /* ----------------- SmartCharging keys ----------------------- */ + + ChargeProfileMaxStackLevel = Key("ChargeProfileMaxStackLevel") + ChargingScheduleAllowedChargingRateUnit = Key("ChargingScheduleAllowedChargingRateUnit") + ChargingScheduleMaxPeriods = Key("ChargingScheduleMaxPeriods") + MaxChargingProfilesInstalled = Key("MaxChargingProfilesInstalled") + ConnectorSwitch3to1PhaseSupported = Key("ConnectorSwitch3to1PhaseSupported") + + /* ----------------- ISO15118 keys ----------------------- */ + CentralContractValidationAllowed = Key("CentralContractValidationAllowed") + CertificateSignedMaxChainSize = Key("CertificateSignedMaxChainSize") + CertSigningWaitMinimum = Key("CertSigningWaitMinimum") + CertSigningRepeatTimes = Key("CertSigningRepeatTimes") + CertificateStoreMaxLength = Key("CertificateStoreMaxLength") + ContractValidationOffline = Key("ContractValidationOffline") + ISO15118PnCEnabled = Key("ISO15118PnCEnabled") + + /* ----------------- Security extension keys ----------------------- */ + AuthorizationData = Key("AuthorizationData") + AdditionalRootCertificateCheck = Key("AdditionalRootCertificateCheck") + CpoName = Key("CpoName") + SecurityProfile = Key("SecurityProfile") +) + +var ( + MandatoryCoreKeys = []Key{ + AuthorizeRemoteTxRequests, + ClockAlignedDataInterval, + ConnectionTimeOut, + GetConfigurationMaxKeys, + HeartbeatInterval, + LocalPreAuthorize, + MeterValuesAlignedData, + MeterValuesSampledData, + MeterValueSampleInterval, + NumberOfConnectors, + ResetRetries, + ConnectorPhaseRotation, + StopTransactionOnEVSideDisconnect, + StopTransactionOnInvalidId, + StopTxnAlignedData, + StopTxnSampledData, + SupportedFeatureProfiles, + TransactionMessageAttempts, + TransactionMessageRetryInterval, + UnlockConnectorOnEVSideDisconnect, + } + + MandatoryLocalAuthKeys = []Key{ + LocalAuthListEnabled, + LocalAuthListMaxLength, + SendLocalListMaxLength, + } + + MandatorySmartChargingKeys = []Key{ + MaxChargingProfilesInstalled, + ChargingScheduleMaxPeriods, + ChargingScheduleAllowedChargingRateUnit, + ChargeProfileMaxStackLevel, + } + + MandatoryFirmwareKeys = []Key{ + SupportedFileTransferProtocols, + } + + MandatoryISO15118Keys = []Key{ + ISO15118PnCEnabled, + ContractValidationOffline, + } + + // Security extension does not have any mandatory keys +) + +func GetMandatoryKeysForProfile(profiles ...string) []Key { + mandatoryKeys := []Key{} + + for _, profile := range profiles { + switch profile { + case core.ProfileName: + mandatoryKeys = append(mandatoryKeys, MandatoryCoreKeys...) + case smartcharging.ProfileName: + mandatoryKeys = append(mandatoryKeys, MandatorySmartChargingKeys...) + case localauth.ProfileName: + mandatoryKeys = append(mandatoryKeys, MandatoryLocalAuthKeys...) + case firmware.ProfileName: + mandatoryKeys = append(mandatoryKeys, MandatoryFirmwareKeys...) + // todo IS15118 mandatory keys validation + } + } + + return mandatoryKeys +} diff --git a/ocpp1.6/config_manager/keys_test.go b/ocpp1.6/config_manager/keys_test.go new file mode 100644 index 00000000..d8cef763 --- /dev/null +++ b/ocpp1.6/config_manager/keys_test.go @@ -0,0 +1,46 @@ +package ocpp_16_config_manager + +import ( + "testing" + + "github.com/stretchr/testify/suite" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" +) + +type keyTestSuite struct { + suite.Suite +} + +func (s *keyTestSuite) TestGetMandatoryKeysForProfile_Core() { + keys := GetMandatoryKeysForProfile(core.ProfileName) + + s.Assert().ElementsMatch(keys, MandatoryCoreKeys) +} + +func (s *keyTestSuite) TestGetMandatoryKeysForProfile_LocalAuth() { + keys := GetMandatoryKeysForProfile(localauth.ProfileName) + + s.Assert().ElementsMatch(keys, MandatoryLocalAuthKeys) +} + +func (s *keyTestSuite) TestGetMandatoryKeysForProfile_Mix() { + keys := GetMandatoryKeysForProfile(core.ProfileName, localauth.ProfileName, firmware.ProfileName, smartcharging.ProfileName) + + expectedKeys := append(MandatoryCoreKeys, MandatoryLocalAuthKeys...) + expectedKeys = append(expectedKeys, MandatoryFirmwareKeys...) + expectedKeys = append(expectedKeys, MandatorySmartChargingKeys...) + + s.Assert().ElementsMatch(keys, expectedKeys) +} + +func (s *keyTestSuite) TestGetMandatoryKeysForProfile_None() { + keys := GetMandatoryKeysForProfile() + s.Assert().Empty(keys) +} + +func TestGetMandatoryKeysForProfile(t *testing.T) { + suite.Run(t, new(keyTestSuite)) +} diff --git a/ocpp1.6/config_manager/manager.go b/ocpp1.6/config_manager/manager.go new file mode 100644 index 00000000..35e06d63 --- /dev/null +++ b/ocpp1.6/config_manager/manager.go @@ -0,0 +1,177 @@ +package ocpp_16_config_manager + +import ( + "errors" + "fmt" + "sync" + + "github.com/agrison/go-commons-lang/stringUtils" + "github.com/samber/lo" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" +) + +var ErrKeyCannotBeEmpty = errors.New("key cannot be empty") + +type ( + KeyValidator func(Key Key, value *string) bool + OnUpdateHandler func(value *string) error + + Manager interface { + SetMandatoryKeys(mandatoryKeys []Key) error + GetMandatoryKeys() []Key + RegisterCustomKeyValidator(KeyValidator) + ValidateKey(key Key, value *string) error + UpdateKey(key Key, value *string) error + OnUpdateKey(key Key, handler OnUpdateHandler) error + GetConfigurationValue(key Key) (*string, error) + SetConfiguration(configuration Config) error + GetConfiguration() ([]core.ConfigurationKey, error) + } + + ManagerV16 struct { + ocppConfig *Config + mandatoryKeys []Key + keyValidator KeyValidator + onUpdateHandlers map[Key]OnUpdateHandler + mu sync.Mutex + } +) + +func NewV16ConfigurationManager(defaultConfiguration Config, profiles ...string) (*ManagerV16, error) { + mandatoryKeys := GetMandatoryKeysForProfile(profiles...) + + // Validate default configuration + err := defaultConfiguration.Validate(mandatoryKeys) + if err != nil { + return nil, err + } + + return &ManagerV16{ + ocppConfig: &defaultConfiguration, + mandatoryKeys: mandatoryKeys, + onUpdateHandlers: make(map[Key]OnUpdateHandler), + mu: sync.Mutex{}, + }, nil +} + +// SetConfiguration validates the provided and overwrites the current configuration +func (m *ManagerV16) SetConfiguration(configuration Config) error { + m.mu.Lock() + defer m.mu.Unlock() + + // Validate the configuration before setting it + err := configuration.Validate(m.mandatoryKeys) + if err != nil { + return err + } + + m.ocppConfig = &configuration + return nil +} + +// RegisterCustomKeyValidator registers a custom key validator +func (m *ManagerV16) RegisterCustomKeyValidator(validator KeyValidator) { + m.keyValidator = validator +} + +// GetMandatoryKeys returns the mandatory keys for the configuration +func (m *ManagerV16) GetMandatoryKeys() []Key { + return m.mandatoryKeys +} + +// SetMandatoryKeys sets the mandatory keys for the configuration +func (m *ManagerV16) SetMandatoryKeys(mandatoryKeys []Key) error { + m.mu.Lock() + defer m.mu.Unlock() + + for _, key := range mandatoryKeys { + isAlreadyPresent := lo.ContainsBy(m.mandatoryKeys, func(k Key) bool { + return k.String() == key.String() + }) + + if isAlreadyPresent { + continue + } + + m.mandatoryKeys = append(m.mandatoryKeys, key) + } + + return nil +} + +// UpdateKey updates the value of a specific key +func (m *ManagerV16) UpdateKey(key Key, value *string) error { + m.mu.Lock() + defer m.mu.Unlock() + + // Validate the key + err := m.ValidateKey(key, value) + if err != nil { + return err + } + + // Try to update the key + err = m.ocppConfig.UpdateKey(key.String(), value) + if err != nil { + return err + } + + // Call the update handler if present + handler, isFound := m.onUpdateHandlers[key] + if isFound { + defer func() { + err = handler(value) + if err != nil { + return + } + }() + } + + return nil +} + +// GetConfiguration returns the full current configuration +func (m *ManagerV16) GetConfiguration() ([]core.ConfigurationKey, error) { + m.mu.Lock() + defer m.mu.Unlock() + + return m.ocppConfig.GetConfig(), nil +} + +// GetConfigurationValue returns the value of a specific key +func (m *ManagerV16) GetConfigurationValue(key Key) (*string, error) { + m.mu.Lock() + defer m.mu.Unlock() + + return m.ocppConfig.GetConfigurationValue(key.String()) +} + +// ValidateKey validates a specific key by checking if there is a custom validator registered +func (m *ManagerV16) ValidateKey(key Key, value *string) error { + if m.keyValidator == nil { + return nil + } + + isValid := m.keyValidator(key, value) + if !isValid { + return fmt.Errorf("key validation failed for key %s", key) + } + + return nil +} + +// OnUpdateKey registers a function to call after a specific key has been updated. +func (m *ManagerV16) OnUpdateKey(key Key, handler OnUpdateHandler) error { + if stringUtils.IsEmpty(key.String()) { + return ErrKeyCannotBeEmpty + } + + // Validate that the key exists + _, err := m.ocppConfig.GetConfigurationValue(key.String()) + if err != nil { + return err + } + + m.onUpdateHandlers[key] = handler + return nil +} diff --git a/ocpp1.6/config_manager/manager_test.go b/ocpp1.6/config_manager/manager_test.go new file mode 100644 index 00000000..9229c13f --- /dev/null +++ b/ocpp1.6/config_manager/manager_test.go @@ -0,0 +1,211 @@ +package ocpp_16_config_manager + +import ( + "strings" + "testing" + + "github.com/samber/lo" + "github.com/stretchr/testify/suite" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" +) + +type ConfigurationManagerTestSuite struct { + suite.Suite + manager *ManagerV16 +} + +func (s *ConfigurationManagerTestSuite) SetupTest() { + profiles := []string{core.ProfileName, smartcharging.ProfileName, localauth.ProfileName} + configuration, err := DefaultConfigurationFromProfiles(profiles...) + s.Require().NoError(err) + + s.manager, err = NewV16ConfigurationManager(*configuration, profiles...) + s.Assert().NoError(err) +} + +func (s *ConfigurationManagerTestSuite) TestNewV16ConfigurationManager() { + configuration, err := DefaultConfigurationFromProfiles(core.ProfileName) + s.Assert().NoError(err) + + // Valid configuration + manager, err := NewV16ConfigurationManager(*configuration, core.ProfileName) + s.Assert().NoError(err) + s.Assert().NotNil(manager) + + // Invalid configuration + manager, err = NewV16ConfigurationManager(NewEmptyConfiguration(), core.ProfileName) + s.Assert().Error(err) + s.Assert().Nil(manager) +} + +func (s *ConfigurationManagerTestSuite) TestGetConfiguration() { + // todo +} + +func (s *ConfigurationManagerTestSuite) TestUpdateConfiguration() { + // Key found + err := s.manager.UpdateKey(HeartbeatInterval, lo.ToPtr("123")) + s.Assert().NoError(err) + + value, err := s.manager.GetConfigurationValue(HeartbeatInterval) + s.Assert().NoError(err) + s.Assert().NotNil(value) + s.Assert().Equal("123", *value) + + err = s.manager.UpdateKey(HeartbeatInterval, nil) + s.Assert().NoError(err) + + value, err = s.manager.GetConfigurationValue(HeartbeatInterval) + s.Assert().NoError(err) + s.Assert().Nil(value) + + // Key not found + err = s.manager.UpdateKey("ExampleKey", lo.ToPtr("exampleValue")) + s.Assert().Error(err) + + err = s.manager.UpdateKey("", lo.ToPtr("exampleValue")) + s.Assert().Error(err) + + err = s.manager.UpdateKey("", nil) + s.Assert().Error(err) +} + +func (s *ConfigurationManagerTestSuite) TestGetConfigurationValue() { + // Tested in the UpdateConfiguration test +} + +func (s *ConfigurationManagerTestSuite) TestOnUpdateKey() { + numExecutions := 0 + + err := s.manager.OnUpdateKey(HeartbeatInterval, func(value *string) error { + numExecutions++ + return nil + }) + _ = s.manager.UpdateKey(HeartbeatInterval, lo.ToPtr("exampleValue")) + _ = s.manager.UpdateKey(HeartbeatInterval, lo.ToPtr("exampleValue")) + _ = s.manager.UpdateKey(HeartbeatInterval, lo.ToPtr("exampleValue")) + s.Assert().NoError(err) + s.Assert().Equal(3, numExecutions) + + err = s.manager.OnUpdateKey("ExampleKey", func(value *string) error { + return nil + }) + s.Assert().Error(err) + + err = s.manager.UpdateKey("ExampleKey", lo.ToPtr("exampleValue")) + s.Assert().Error(err) + + err = s.manager.OnUpdateKey("", func(value *string) error { + numExecutions++ + return nil + }) + s.Assert().Error(err) + + err = s.manager.UpdateKey("", lo.ToPtr("exampleValue")) + s.Assert().Error(err) + s.Assert().Equal(3, numExecutions) +} + +func (s *ConfigurationManagerTestSuite) TestSetConfiguration() { + // todo +} + +func (s *ConfigurationManagerTestSuite) TestValidateKey() { + + s.manager.RegisterCustomKeyValidator(func(key Key, value *string) bool { + switch key { + case HeartbeatInterval: + if value == nil { + return false + } + return true + case LocalAuthListEnabled: + if value == nil { + return false + } + + if strings.ToUpper(*value) == "TRUE" || strings.ToUpper(*value) == "FALSE" { + return true + } + + return false + default: + return false + } + }) + + err := s.manager.ValidateKey(HeartbeatInterval, lo.ToPtr("123")) + s.Assert().NoError(err) + // Should fail - invalid value + err = s.manager.ValidateKey(HeartbeatInterval, nil) + s.Assert().Error(err) + + err = s.manager.ValidateKey(LocalAuthListEnabled, lo.ToPtr("true")) + s.Assert().NoError(err) + + err = s.manager.ValidateKey(LocalAuthListEnabled, lo.ToPtr("false")) + s.Assert().NoError(err) + + // Should fail - invalid value + err = s.manager.ValidateKey(LocalAuthListEnabled, nil) + s.Assert().Error(err) + + err = s.manager.ValidateKey(LocalAuthListEnabled, lo.ToPtr("aaaaa")) + s.Assert().Error(err) + + // Should fail - invalid key + err = s.manager.ValidateKey("ABCD", lo.ToPtr("aaaaa")) + s.Assert().Error(err) + + err = s.manager.ValidateKey("ABCD", nil) + s.Assert().Error(err) +} + +func (s *ConfigurationManagerTestSuite) TestRegisterCustomKeyValidator() { + exampleKey := Key("ExampleKey") + numExecutions := 0 + + s.manager.RegisterCustomKeyValidator(func(key Key, value *string) bool { + numExecutions++ + return exampleKey == key && value != nil && *value == "exampleValue" + }) + + _ = s.manager.UpdateKey(exampleKey, lo.ToPtr("exampleValue")) + s.Assert().Equal(1, numExecutions) +} + +func (s *ConfigurationManagerTestSuite) TestGetMandatoryKeys() { + configuration, err := DefaultConfigurationFromProfiles(core.ProfileName) + s.Assert().NoError(err) + + // Valid configuration + manager, err := NewV16ConfigurationManager(*configuration, core.ProfileName) + s.Assert().NoError(err) + + s.ElementsMatch(MandatoryCoreKeys, manager.GetMandatoryKeys()) + + configuration, err = DefaultConfigurationFromProfiles(core.ProfileName, localauth.ProfileName) + s.Assert().NoError(err) + manager, err = NewV16ConfigurationManager(*configuration, core.ProfileName, localauth.ProfileName) + s.Assert().NoError(err) + + keys := append(MandatoryCoreKeys, MandatoryLocalAuthKeys...) + s.ElementsMatch(keys, manager.GetMandatoryKeys()) +} + +func (s *ConfigurationManagerTestSuite) TestSetMandatoryKeys() { + configuration, err := DefaultConfigurationFromProfiles(core.ProfileName) + s.Assert().NoError(err) + + // Valid configuration + manager, err := NewV16ConfigurationManager(*configuration, core.ProfileName) + s.Assert().NoError(err) + s.Assert().NotNil(manager) + +} + +func TestConfigurationManager(t *testing.T) { + suite.Run(t, new(ConfigurationManagerTestSuite)) +} diff --git a/ocpp1.6/core/authorize.go b/ocpp1.6/core/authorize.go index 3a9874ad..862cadb8 100644 --- a/ocpp1.6/core/authorize.go +++ b/ocpp1.6/core/authorize.go @@ -1,7 +1,7 @@ package core import ( - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "reflect" ) diff --git a/ocpp1.6/core/boot_notification.go b/ocpp1.6/core/boot_notification.go index b3e63b05..14e1fb04 100644 --- a/ocpp1.6/core/boot_notification.go +++ b/ocpp1.6/core/boot_notification.go @@ -1,7 +1,7 @@ package core import ( - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" "reflect" ) diff --git a/ocpp1.6/core/change_availability.go b/ocpp1.6/core/change_availability.go index b0ce5be8..a7407f72 100644 --- a/ocpp1.6/core/change_availability.go +++ b/ocpp1.6/core/change_availability.go @@ -1,7 +1,7 @@ package core import ( - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" "reflect" ) diff --git a/ocpp1.6/core/change_configuration.go b/ocpp1.6/core/change_configuration.go index a0e250fd..fb88c285 100644 --- a/ocpp1.6/core/change_configuration.go +++ b/ocpp1.6/core/change_configuration.go @@ -1,7 +1,7 @@ package core import ( - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" "reflect" ) diff --git a/ocpp1.6/core/clear_cache.go b/ocpp1.6/core/clear_cache.go index 4d6204ad..617969ec 100644 --- a/ocpp1.6/core/clear_cache.go +++ b/ocpp1.6/core/clear_cache.go @@ -1,7 +1,7 @@ package core import ( - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" "reflect" ) diff --git a/ocpp1.6/core/core.go b/ocpp1.6/core/core.go index bb504a35..0eab8fa0 100644 --- a/ocpp1.6/core/core.go +++ b/ocpp1.6/core/core.go @@ -2,7 +2,7 @@ package core import ( - "github.com/lorenzodonini/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp" ) // Needs to be implemented by Central systems for handling messages part of the OCPP 1.6 Core profile. diff --git a/ocpp1.6/core/data_transfer.go b/ocpp1.6/core/data_transfer.go index bca7358a..21fefe59 100644 --- a/ocpp1.6/core/data_transfer.go +++ b/ocpp1.6/core/data_transfer.go @@ -1,7 +1,7 @@ package core import ( - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" "reflect" ) diff --git a/ocpp1.6/core/heartbeat.go b/ocpp1.6/core/heartbeat.go index a49406cb..0376d318 100644 --- a/ocpp1.6/core/heartbeat.go +++ b/ocpp1.6/core/heartbeat.go @@ -1,7 +1,7 @@ package core import ( - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" "reflect" ) diff --git a/ocpp1.6/core/meter_values.go b/ocpp1.6/core/meter_values.go index 68ea499d..e1dc9945 100644 --- a/ocpp1.6/core/meter_values.go +++ b/ocpp1.6/core/meter_values.go @@ -3,7 +3,7 @@ package core import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // -------------------- MeterValues (CP -> CS) -------------------- diff --git a/ocpp1.6/core/remote_start_transaction.go b/ocpp1.6/core/remote_start_transaction.go index 2b008077..9fffb86b 100644 --- a/ocpp1.6/core/remote_start_transaction.go +++ b/ocpp1.6/core/remote_start_transaction.go @@ -3,7 +3,7 @@ package core import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // -------------------- Remote Start Transaction (CS -> CP) -------------------- diff --git a/ocpp1.6/core/remote_stop_transaction.go b/ocpp1.6/core/remote_stop_transaction.go index ddf94c79..6e4957b9 100644 --- a/ocpp1.6/core/remote_stop_transaction.go +++ b/ocpp1.6/core/remote_stop_transaction.go @@ -3,7 +3,7 @@ package core import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // -------------------- Remote Stop Transaction (CS -> CP) -------------------- diff --git a/ocpp1.6/core/reset.go b/ocpp1.6/core/reset.go index 7ef0770d..6b5c7b24 100644 --- a/ocpp1.6/core/reset.go +++ b/ocpp1.6/core/reset.go @@ -3,7 +3,7 @@ package core import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp1.6/core/start_transaction.go b/ocpp1.6/core/start_transaction.go index 3b3bdaf6..4fcae861 100644 --- a/ocpp1.6/core/start_transaction.go +++ b/ocpp1.6/core/start_transaction.go @@ -1,7 +1,7 @@ package core import ( - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "reflect" ) diff --git a/ocpp1.6/core/status_notification.go b/ocpp1.6/core/status_notification.go index 130d3913..d31365a9 100644 --- a/ocpp1.6/core/status_notification.go +++ b/ocpp1.6/core/status_notification.go @@ -1,7 +1,7 @@ package core import ( - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" "reflect" ) diff --git a/ocpp1.6/core/stop_transaction.go b/ocpp1.6/core/stop_transaction.go index 1e97f482..85b9e93f 100644 --- a/ocpp1.6/core/stop_transaction.go +++ b/ocpp1.6/core/stop_transaction.go @@ -3,7 +3,7 @@ package core import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp1.6/core/unlock_connector.go b/ocpp1.6/core/unlock_connector.go index 165da681..c8bc0ad2 100644 --- a/ocpp1.6/core/unlock_connector.go +++ b/ocpp1.6/core/unlock_connector.go @@ -1,7 +1,7 @@ package core import ( - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" "reflect" ) diff --git a/ocpp1.6/extendedtriggermessage/extended_trigger_message.go b/ocpp1.6/extendedtriggermessage/extended_trigger_message.go index 683a3cdd..5675ef1b 100644 --- a/ocpp1.6/extendedtriggermessage/extended_trigger_message.go +++ b/ocpp1.6/extendedtriggermessage/extended_trigger_message.go @@ -3,7 +3,7 @@ package extendedtriggermessage import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp1.6/extendedtriggermessage/trigger_message.go b/ocpp1.6/extendedtriggermessage/trigger_message.go index 3431e78c..9cdfb3c0 100644 --- a/ocpp1.6/extendedtriggermessage/trigger_message.go +++ b/ocpp1.6/extendedtriggermessage/trigger_message.go @@ -1,7 +1,7 @@ // The diagnostics functional block contains OCPP 2.0 features than enable remote diagnostics of problems with a charging station. package extendedtriggermessage -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by Charging stations for handling messages part of the OCPP 1.6j security extension. type ChargePointHandler interface { diff --git a/ocpp1.6/firmware/diagnostics_status_notification.go b/ocpp1.6/firmware/diagnostics_status_notification.go index 5dcfb81f..92c5e39d 100644 --- a/ocpp1.6/firmware/diagnostics_status_notification.go +++ b/ocpp1.6/firmware/diagnostics_status_notification.go @@ -1,7 +1,7 @@ package firmware import ( - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" "reflect" ) diff --git a/ocpp1.6/firmware/firmware.go b/ocpp1.6/firmware/firmware.go index c1351ba7..82cd2b4e 100644 --- a/ocpp1.6/firmware/firmware.go +++ b/ocpp1.6/firmware/firmware.go @@ -2,7 +2,7 @@ package firmware import ( - "github.com/lorenzodonini/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp" ) // Needs to be implemented by Central systems for handling messages part of the OCPP 1.6 FirmwareManagement profile. diff --git a/ocpp1.6/firmware/firmware_status_notification.go b/ocpp1.6/firmware/firmware_status_notification.go index 06e6b2ed..66912a9a 100644 --- a/ocpp1.6/firmware/firmware_status_notification.go +++ b/ocpp1.6/firmware/firmware_status_notification.go @@ -1,7 +1,7 @@ package firmware import ( - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" "reflect" ) diff --git a/ocpp1.6/firmware/get_diagnostics.go b/ocpp1.6/firmware/get_diagnostics.go index bf4d93cc..cebef9ed 100644 --- a/ocpp1.6/firmware/get_diagnostics.go +++ b/ocpp1.6/firmware/get_diagnostics.go @@ -3,7 +3,7 @@ package firmware import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // -------------------- Get Diagnostics (CS -> CP) -------------------- diff --git a/ocpp1.6/firmware/update_firmware.go b/ocpp1.6/firmware/update_firmware.go index e94a33af..641b748d 100644 --- a/ocpp1.6/firmware/update_firmware.go +++ b/ocpp1.6/firmware/update_firmware.go @@ -1,7 +1,7 @@ package firmware import ( - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "reflect" ) diff --git a/ocpp1.6/localauth/local_auth_list.go b/ocpp1.6/localauth/local_auth_list.go index 1357674a..d8874303 100644 --- a/ocpp1.6/localauth/local_auth_list.go +++ b/ocpp1.6/localauth/local_auth_list.go @@ -1,7 +1,7 @@ // Contains features to manage the local authorization list in Charge Points. package localauth -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by Central systems for handling messages part of the OCPP 1.6 LocalAuthList profile. type CentralSystemHandler interface { diff --git a/ocpp1.6/localauth/send_local_list.go b/ocpp1.6/localauth/send_local_list.go index d1107ebf..92153c87 100644 --- a/ocpp1.6/localauth/send_local_list.go +++ b/ocpp1.6/localauth/send_local_list.go @@ -1,7 +1,7 @@ package localauth import ( - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" "reflect" ) diff --git a/ocpp1.6/logging/get_log.go b/ocpp1.6/logging/get_log.go index 0878c0bc..62e8c74f 100644 --- a/ocpp1.6/logging/get_log.go +++ b/ocpp1.6/logging/get_log.go @@ -3,7 +3,7 @@ package logging import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp1.6/logging/log.go b/ocpp1.6/logging/log.go index 7a8e875d..f5bc821f 100644 --- a/ocpp1.6/logging/log.go +++ b/ocpp1.6/logging/log.go @@ -1,7 +1,7 @@ // The diagnostics functional block contains OCPP 2.0 features than enable remote diagnostics of problems with a charging station. package logging -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by a CSMS for handling messages part of the OCPP 1.6j security extension. type CentralSystemHandler interface { diff --git a/ocpp1.6/logging/log_status_notification.go b/ocpp1.6/logging/log_status_notification.go index d9d62470..279a8026 100644 --- a/ocpp1.6/logging/log_status_notification.go +++ b/ocpp1.6/logging/log_status_notification.go @@ -3,7 +3,7 @@ package logging import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp1.6/remotetrigger/remote_trigger.go b/ocpp1.6/remotetrigger/remote_trigger.go index 721aa97a..d773a7bf 100644 --- a/ocpp1.6/remotetrigger/remote_trigger.go +++ b/ocpp1.6/remotetrigger/remote_trigger.go @@ -1,7 +1,7 @@ // Contains support for remote triggering of Charge Point initiated messages. package remotetrigger -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by Central systems for handling messages part of the OCPP 1.6 RemoteTrigger profile. type CentralSystemHandler interface { diff --git a/ocpp1.6/remotetrigger/trigger_message.go b/ocpp1.6/remotetrigger/trigger_message.go index 35379da0..2df0cb53 100644 --- a/ocpp1.6/remotetrigger/trigger_message.go +++ b/ocpp1.6/remotetrigger/trigger_message.go @@ -3,9 +3,9 @@ package remotetrigger import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp1.6/reservation/cancel_reservation.go b/ocpp1.6/reservation/cancel_reservation.go index c6f14a8c..a94752c5 100644 --- a/ocpp1.6/reservation/cancel_reservation.go +++ b/ocpp1.6/reservation/cancel_reservation.go @@ -1,7 +1,7 @@ package reservation import ( - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" "reflect" ) diff --git a/ocpp1.6/reservation/reservation.go b/ocpp1.6/reservation/reservation.go index d393444a..22be108b 100644 --- a/ocpp1.6/reservation/reservation.go +++ b/ocpp1.6/reservation/reservation.go @@ -1,7 +1,7 @@ // Contains support for reservation of a Charge Point. package reservation -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by Central systems for handling messages part of the OCPP 1.6 Reservation profile. type CentralSystemHandler interface { diff --git a/ocpp1.6/reservation/reserve_now.go b/ocpp1.6/reservation/reserve_now.go index 6bceadd2..73a667e0 100644 --- a/ocpp1.6/reservation/reserve_now.go +++ b/ocpp1.6/reservation/reserve_now.go @@ -1,7 +1,7 @@ package reservation import ( - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" "reflect" ) diff --git a/ocpp1.6/securefirmware/secure_firmware.go b/ocpp1.6/securefirmware/secure_firmware.go index dfd41ba6..1a8d988c 100644 --- a/ocpp1.6/securefirmware/secure_firmware.go +++ b/ocpp1.6/securefirmware/secure_firmware.go @@ -1,7 +1,7 @@ // The diagnostics functional block contains OCPP 1.6J extension features than enable remote firmware updates on charging stations. package securefirmware -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" type CentralSystemHandler interface { OnSignedFirmwareStatusNotification(chargingStationID string, request *SignedFirmwareStatusNotificationRequest) (response *SignedFirmwareStatusNotificationResponse, err error) diff --git a/ocpp1.6/securefirmware/signed_update_firmware.go b/ocpp1.6/securefirmware/signed_update_firmware.go index d688d016..50eeb4fb 100644 --- a/ocpp1.6/securefirmware/signed_update_firmware.go +++ b/ocpp1.6/securefirmware/signed_update_firmware.go @@ -3,7 +3,7 @@ package securefirmware import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp1.6/securefirmware/signed_update_firmware_status_notitfication.go b/ocpp1.6/securefirmware/signed_update_firmware_status_notitfication.go index b4d063e5..e6d39471 100644 --- a/ocpp1.6/securefirmware/signed_update_firmware_status_notitfication.go +++ b/ocpp1.6/securefirmware/signed_update_firmware_status_notitfication.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // -------------------- Firmware Status Notification (CS -> CSMS) -------------------- diff --git a/ocpp1.6/security/certificate_signed.go b/ocpp1.6/security/certificate_signed.go index 51832dee..3472b7c1 100644 --- a/ocpp1.6/security/certificate_signed.go +++ b/ocpp1.6/security/certificate_signed.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // -------------------- Certificate Signed (CSMS -> CS) -------------------- diff --git a/ocpp1.6/security/security.go b/ocpp1.6/security/security.go index 7a417222..49d57c8a 100644 --- a/ocpp1.6/security/security.go +++ b/ocpp1.6/security/security.go @@ -1,7 +1,7 @@ // The security functional block contains OCPP 2.0 features aimed at providing E2E security between a CSMS and a Charging station. package security -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Security profile. type CentralSystemHandler interface { diff --git a/ocpp1.6/security/security_event_notification.go b/ocpp1.6/security/security_event_notification.go index 15a4ab02..98461885 100644 --- a/ocpp1.6/security/security_event_notification.go +++ b/ocpp1.6/security/security_event_notification.go @@ -3,7 +3,7 @@ package security import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // -------------------- Security Event Notification Status (CS -> CSMS) -------------------- diff --git a/ocpp1.6/security/sign_certificate.go b/ocpp1.6/security/sign_certificate.go index cdf79863..33adf4e2 100644 --- a/ocpp1.6/security/sign_certificate.go +++ b/ocpp1.6/security/sign_certificate.go @@ -3,7 +3,7 @@ package security import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // -------------------- Sign Certificate (CS -> CSMS) -------------------- diff --git a/ocpp1.6/smartcharging/clear_charging_profile.go b/ocpp1.6/smartcharging/clear_charging_profile.go index 7a7a3ef1..1090cc07 100644 --- a/ocpp1.6/smartcharging/clear_charging_profile.go +++ b/ocpp1.6/smartcharging/clear_charging_profile.go @@ -3,7 +3,7 @@ package smartcharging import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp1.6/smartcharging/get_composite_schedule.go b/ocpp1.6/smartcharging/get_composite_schedule.go index 7d64f614..f7a36393 100644 --- a/ocpp1.6/smartcharging/get_composite_schedule.go +++ b/ocpp1.6/smartcharging/get_composite_schedule.go @@ -3,7 +3,7 @@ package smartcharging import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp1.6/smartcharging/set_charging_profile.go b/ocpp1.6/smartcharging/set_charging_profile.go index 4694d32a..62a6ee64 100644 --- a/ocpp1.6/smartcharging/set_charging_profile.go +++ b/ocpp1.6/smartcharging/set_charging_profile.go @@ -3,7 +3,7 @@ package smartcharging import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp1.6/smartcharging/smart_charging.go b/ocpp1.6/smartcharging/smart_charging.go index 2b7a06f5..91265be3 100644 --- a/ocpp1.6/smartcharging/smart_charging.go +++ b/ocpp1.6/smartcharging/smart_charging.go @@ -1,7 +1,7 @@ // Contains support for basic Smart Charging, for instance using control pilot. package smartcharging -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by Central systems for handling messages part of the OCPP 1.6 SmartCharging profile. type CentralSystemHandler interface { diff --git a/ocpp1.6/types/types.go b/ocpp1.6/types/types.go index bb3cd501..f045a826 100644 --- a/ocpp1.6/types/types.go +++ b/ocpp1.6/types/types.go @@ -2,7 +2,7 @@ package types import ( - "github.com/lorenzodonini/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ocppj" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp1.6/v16.go b/ocpp1.6/v16.go index 4fada30f..f19f1707 100644 --- a/ocpp1.6/v16.go +++ b/ocpp1.6/v16.go @@ -5,22 +5,23 @@ import ( "crypto/tls" "net" - "github.com/lorenzodonini/ocpp-go/internal/callbackqueue" - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/certificates" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/extendedtriggermessage" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/logging" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/remotetrigger" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/securefirmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/security" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/lorenzodonini/ocpp-go/ocppj" - "github.com/lorenzodonini/ocpp-go/ws" + "github.com/xBlaz3kx/ocpp-go/internal/callbackqueue" + log "github.com/xBlaz3kx/ocpp-go/logging" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/certificates" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/extendedtriggermessage" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/logging" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/remotetrigger" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/securefirmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/security" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ws" ) type ChargePointConnection interface { @@ -159,19 +160,22 @@ type ChargePoint interface { // // For more advanced options, or if a customer networking/occpj layer is required, // please refer to ocppj.Client and ws.Client. -func NewChargePoint(id string, endpoint *ocppj.Client, client ws.Client) ChargePoint { +func NewChargePoint(id string, endpoint *ocppj.Client, client ws.Client, logger log.Logger) (ChargePoint, error) { if client == nil { client = ws.NewClient() } + client.SetRequestedSubProtocol(types.V16Subprotocol) + var err error if endpoint == nil { - dispatcher := ocppj.NewDefaultClientDispatcher(ocppj.NewFIFOClientQueue(0)) - endpoint = ocppj.NewClient( + dispatcher := ocppj.NewDefaultClientDispatcher(ocppj.NewFIFOClientQueue(0), logger) + endpoint, err = ocppj.NewClient( id, client, dispatcher, nil, + logger, core.Profile, localauth.Profile, firmware.Profile, @@ -185,6 +189,10 @@ func NewChargePoint(id string, endpoint *ocppj.Client, client ws.Client) ChargeP securefirmware.Profile, ) } + if err != nil { + return nil, err + } + endpoint.SetDialect(ocpp.V16) cp := chargePoint{ @@ -204,7 +212,8 @@ func NewChargePoint(id string, endpoint *ocppj.Client, client ws.Client) ChargeP cp.errorHandler <- err }) cp.client.SetRequestHandler(cp.handleIncomingRequest) - return &cp + + return &cp, nil } // -------------------- v1.6 Central System -------------------- @@ -339,13 +348,15 @@ type CentralSystem interface { // If you need a TLS server, you may use the following: // // cs := NewServer(nil, ws.NewServer(ws.WithServerTLSConfig("certificatePath", "privateKeyPath", nil))) -func NewCentralSystem(endpoint *ocppj.Server, server ws.Server) CentralSystem { +func NewCentralSystem(endpoint *ocppj.Server, server ws.Server, logger log.Logger) (CentralSystem, error) { if server == nil { server = ws.NewServer() } server.AddSupportedSubprotocol(types.V16Subprotocol) + + var err error if endpoint == nil { - endpoint = ocppj.NewServer(server, nil, nil, + endpoint, err = ocppj.NewServer(server, nil, nil, logger, core.Profile, localauth.Profile, firmware.Profile, @@ -358,8 +369,16 @@ func NewCentralSystem(endpoint *ocppj.Server, server ws.Server) CentralSystem { certificates.Profile, securefirmware.Profile, ) + if err != nil { + return nil, err + } + } + + cs, err := newCentralSystem(endpoint) + if err != nil { + return nil, err } - cs := newCentralSystem(endpoint) + cs.server.SetRequestHandler(func(client ws.Channel, request ocpp.Request, requestId string, action string) { cs.handleIncomingRequest(client, request, requestId, action) }) @@ -372,5 +391,5 @@ func NewCentralSystem(endpoint *ocppj.Server, server ws.Server) CentralSystem { cs.server.SetCanceledRequestHandler(func(clientID string, requestID string, request ocpp.Request, err *ocpp.Error) { cs.handleCanceledRequest(clientID, request, err) }) - return &cs + return &cs, nil } diff --git a/ocpp1.6_test/authorize_test.go b/ocpp1.6_test/authorize_test.go index 665b36f1..db5301bb 100644 --- a/ocpp1.6_test/authorize_test.go +++ b/ocpp1.6_test/authorize_test.go @@ -4,36 +4,31 @@ import ( "fmt" "time" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Test func (suite *OcppV16TestSuite) TestAuthorizeRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {core.AuthorizeRequest{IdTag: "12345"}, true}, {core.AuthorizeRequest{}, false}, {core.AuthorizeRequest{IdTag: ">20.................."}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestAuthorizeConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {core.AuthorizeConfirmation{IdTagInfo: &types.IdTagInfo{ExpiryDate: types.NewDateTime(time.Now().Add(time.Hour * 8)), ParentIdTag: "00000", Status: types.AuthorizationStatusAccepted}}, true}, {core.AuthorizeConfirmation{IdTagInfo: &types.IdTagInfo{Status: "invalidAuthorizationStatus"}}, false}, {core.AuthorizeConfirmation{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestAuthorizeE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -52,22 +47,22 @@ func (suite *OcppV16TestSuite) TestAuthorizeE2EMocked() { coreListener := &MockCentralSystemCoreListener{} coreListener.On("OnAuthorize", mock.AnythingOfType("string"), mock.Anything).Return(authorizeConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*core.AuthorizeRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, idTag, request.IdTag) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(idTag, request.IdTag) }) setupDefaultCentralSystemHandlers(suite, coreListener, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: responseRaw, forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, nil, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: requestRaw, forwardWrittenMessage: true}) // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) confirmation, err := suite.chargePoint.Authorize(idTag) - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.IdTagInfo.Status) - assert.Equal(t, parentIdTag, confirmation.IdTagInfo.ParentIdTag) - assertDateTimeEquality(t, *expiryDate, *confirmation.IdTagInfo.ExpiryDate) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.IdTagInfo.Status) + suite.Equal(parentIdTag, confirmation.IdTagInfo.ParentIdTag) + assertDateTimeEquality(suite, *expiryDate, *confirmation.IdTagInfo.ExpiryDate) } func (suite *OcppV16TestSuite) TestAuthorizeInvalidEndpoint() { diff --git a/ocpp1.6_test/boot_notification_test.go b/ocpp1.6_test/boot_notification_test.go index 90b33f33..938a48c1 100644 --- a/ocpp1.6_test/boot_notification_test.go +++ b/ocpp1.6_test/boot_notification_test.go @@ -4,16 +4,13 @@ import ( "fmt" "time" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Tests func (suite *OcppV16TestSuite) TestBootNotificationRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {core.BootNotificationRequest{ChargePointModel: "test", ChargePointVendor: "test"}, true}, {core.BootNotificationRequest{ChargeBoxSerialNumber: "test", ChargePointModel: "test", ChargePointSerialNumber: "number", ChargePointVendor: "test", FirmwareVersion: "version", Iccid: "test", Imsi: "test"}, true}, @@ -29,11 +26,10 @@ func (suite *OcppV16TestSuite) TestBootNotificationRequestValidation() { {core.BootNotificationRequest{ChargePointModel: "test", ChargePointVendor: "test", MeterSerialNumber: ">25......................."}, false}, {core.BootNotificationRequest{ChargePointModel: "test", ChargePointVendor: "test", MeterType: ">25......................."}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestBootNotificationConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {core.BootNotificationConfirmation{CurrentTime: types.NewDateTime(time.Now()), Interval: 60, Status: core.RegistrationStatusAccepted}, true}, {core.BootNotificationConfirmation{CurrentTime: types.NewDateTime(time.Now()), Interval: 60, Status: core.RegistrationStatusPending}, true}, @@ -44,11 +40,10 @@ func (suite *OcppV16TestSuite) TestBootNotificationConfirmationValidation() { {core.BootNotificationConfirmation{CurrentTime: types.NewDateTime(time.Now()), Interval: 60}, false}, {core.BootNotificationConfirmation{Interval: 60, Status: core.RegistrationStatusAccepted}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestBootNotificationE2EMocked() { - t := suite.T() wsId := "test_id" messageId := "1234" wsUrl := "someUrl" @@ -65,23 +60,23 @@ func (suite *OcppV16TestSuite) TestBootNotificationE2EMocked() { coreListener := &MockCentralSystemCoreListener{} coreListener.On("OnBootNotification", mock.AnythingOfType("string"), mock.Anything).Return(bootNotificationConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*core.BootNotificationRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, chargePointModel, request.ChargePointModel) - assert.Equal(t, chargePointVendor, request.ChargePointVendor) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(chargePointModel, request.ChargePointModel) + suite.Equal(chargePointVendor, request.ChargePointVendor) }) setupDefaultCentralSystemHandlers(suite, coreListener, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, nil, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) confirmation, err := suite.chargePoint.BootNotification(chargePointModel, chargePointVendor) - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, registrationStatus, confirmation.Status) - assert.Equal(t, interval, confirmation.Interval) - assertDateTimeEquality(t, *currentTime, *confirmation.CurrentTime) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(registrationStatus, confirmation.Status) + suite.Equal(interval, confirmation.Interval) + assertDateTimeEquality(suite, *currentTime, *confirmation.CurrentTime) } func (suite *OcppV16TestSuite) TestBootNotificationInvalidEndpoint() { diff --git a/ocpp1.6_test/cancel_reservation_test.go b/ocpp1.6_test/cancel_reservation_test.go index d95e809f..2cedd6e1 100644 --- a/ocpp1.6_test/cancel_reservation_test.go +++ b/ocpp1.6_test/cancel_reservation_test.go @@ -3,35 +3,30 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/reservation" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/reservation" ) // Test func (suite *OcppV16TestSuite) TestCancelReservationRequestValidation() { - t := suite.T() requestTable := []GenericTestEntry{ {reservation.CancelReservationRequest{ReservationId: 42}, true}, {reservation.CancelReservationRequest{}, true}, {reservation.CancelReservationRequest{ReservationId: -1}, true}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestCancelReservationConfirmationValidation() { - t := suite.T() confirmationTable := []GenericTestEntry{ {reservation.CancelReservationConfirmation{Status: reservation.CancelReservationStatusAccepted}, true}, {reservation.CancelReservationConfirmation{Status: "invalidCancelReservationStatus"}, false}, {reservation.CancelReservationConfirmation{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestCancelReservationE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -45,9 +40,9 @@ func (suite *OcppV16TestSuite) TestCancelReservationE2EMocked() { reservationListener := &MockChargePointReservationListener{} reservationListener.On("OnCancelReservation", mock.Anything).Return(cancelReservationConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*reservation.CancelReservationRequest) - require.NotNil(t, request) - require.True(t, ok) - assert.Equal(t, reservationId, request.ReservationId) + suite.Require().NotNil(request) + suite.Require().True(ok) + suite.Equal(reservationId, request.ReservationId) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, nil, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) @@ -55,17 +50,17 @@ func (suite *OcppV16TestSuite) TestCancelReservationE2EMocked() { // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.CancelReservation(wsId, func(confirmation *reservation.CancelReservationConfirmation, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, reservationId) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestCancelReservationInvalidEndpoint() { diff --git a/ocpp1.6_test/certificate_signed_test.go b/ocpp1.6_test/certificate_signed_test.go index 6eeb05d5..feec358d 100644 --- a/ocpp1.6_test/certificate_signed_test.go +++ b/ocpp1.6_test/certificate_signed_test.go @@ -3,26 +3,22 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/security" - "github.com/lorenzodonini/ocpp-go/ocpp1.6_test/mocks" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/security" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6_test/mocks" ) func (suite *OcppV16TestSuite) TestCertificateSignedRequestValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {security.CertificateSignedRequest{CertificateChain: "sampleCert"}, true}, {security.CertificateSignedRequest{CertificateChain: ""}, false}, {security.CertificateSignedRequest{}, false}, {security.CertificateSignedRequest{CertificateChain: newLongString(100001)}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV16TestSuite) TestCertificateSignedConfirmationValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {security.CertificateSignedResponse{Status: security.CertificateSignedStatusAccepted}, true}, {security.CertificateSignedResponse{Status: security.CertificateSignedStatusAccepted}, true}, @@ -30,7 +26,7 @@ func (suite *OcppV16TestSuite) TestCertificateSignedConfirmationValidation() { {security.CertificateSignedResponse{Status: "invalidCertificateSignedStatus"}, false}, {security.CertificateSignedResponse{}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } // Test @@ -49,7 +45,7 @@ func (suite *OcppV16TestSuite) TestCertificateSignedE2EMocked() { // Setting handlers handler := mocks.NewMockSecurityChargePointHandler(t) handler.EXPECT().OnCertificateSigned(mock.Anything).RunAndReturn(func(request *security.CertificateSignedRequest) (*security.CertificateSignedResponse, error) { - assert.Equal(t, certificateChain, request.CertificateChain) + suite.Equal(certificateChain, request.CertificateChain) return certificateSignedConfirmation, nil }) @@ -60,19 +56,19 @@ func (suite *OcppV16TestSuite) TestCertificateSignedE2EMocked() { suite.centralSystem.Start(8887, "somePath") suite.chargePoint.SetSecurityHandler(handler) err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.CertificateSigned(wsId, func(confirmation *security.CertificateSignedResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, certificateChain, func(request *security.CertificateSignedRequest) { request.CertificateChain = certificateChain }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestCertificateSignedInvalidEndpoint() { diff --git a/ocpp1.6_test/change_availability_test.go b/ocpp1.6_test/change_availability_test.go index a0192f78..503ed537 100644 --- a/ocpp1.6_test/change_availability_test.go +++ b/ocpp1.6_test/change_availability_test.go @@ -3,14 +3,11 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" ) func (suite *OcppV16TestSuite) TestChangeAvailabilityRequestValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {core.ChangeAvailabilityRequest{ConnectorId: 0, Type: core.AvailabilityTypeOperative}, true}, {core.ChangeAvailabilityRequest{ConnectorId: 0, Type: core.AvailabilityTypeInoperative}, true}, @@ -19,11 +16,10 @@ func (suite *OcppV16TestSuite) TestChangeAvailabilityRequestValidation() { {core.ChangeAvailabilityRequest{Type: "invalidAvailabilityType"}, false}, {core.ChangeAvailabilityRequest{ConnectorId: -1, Type: core.AvailabilityTypeOperative}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV16TestSuite) TestChangeAvailabilityConfirmationValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {core.ChangeAvailabilityConfirmation{Status: core.AvailabilityStatusAccepted}, true}, {core.ChangeAvailabilityConfirmation{Status: core.AvailabilityStatusRejected}, true}, @@ -31,12 +27,11 @@ func (suite *OcppV16TestSuite) TestChangeAvailabilityConfirmationValidation() { {core.ChangeAvailabilityConfirmation{Status: "invalidAvailabilityStatus"}, false}, {core.ChangeAvailabilityConfirmation{}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } // Test func (suite *OcppV16TestSuite) TestChangeAvailabilityE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -51,27 +46,27 @@ func (suite *OcppV16TestSuite) TestChangeAvailabilityE2EMocked() { coreListener := &MockChargePointCoreListener{} coreListener.On("OnChangeAvailability", mock.Anything).Return(changeAvailabilityConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*core.ChangeAvailabilityRequest) - require.NotNil(t, request) - require.True(t, ok) - assert.Equal(t, connectorId, request.ConnectorId) - assert.Equal(t, availabilityType, request.Type) + suite.Require().NotNil(request) + suite.Require().True(ok) + suite.Equal(connectorId, request.ConnectorId) + suite.Equal(availabilityType, request.Type) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, coreListener, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.ChangeAvailability(wsId, func(confirmation *core.ChangeAvailabilityConfirmation, err error) { - require.NotNil(t, confirmation) - require.Nil(t, err) - assert.Equal(t, status, confirmation.Status) + suite.Require().NotNil(confirmation) + suite.Require().Nil(err) + suite.Equal(status, confirmation.Status) resultChannel <- true }, connectorId, availabilityType) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestChangeAvailabilityInvalidEndpoint() { diff --git a/ocpp1.6_test/change_configuration_test.go b/ocpp1.6_test/change_configuration_test.go index 3002bff9..87ce0f05 100644 --- a/ocpp1.6_test/change_configuration_test.go +++ b/ocpp1.6_test/change_configuration_test.go @@ -3,15 +3,12 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" ) // Test func (suite *OcppV16TestSuite) TestChangeConfigurationRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {core.ChangeConfigurationRequest{Key: "someKey", Value: "someValue"}, true}, {core.ChangeConfigurationRequest{Key: "someKey"}, false}, @@ -20,11 +17,10 @@ func (suite *OcppV16TestSuite) TestChangeConfigurationRequestValidation() { {core.ChangeConfigurationRequest{Key: ">50................................................", Value: "someValue"}, false}, {core.ChangeConfigurationRequest{Key: "someKey", Value: ">500................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................."}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestChangeConfigurationConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {core.ChangeConfigurationConfirmation{Status: core.ConfigurationStatusAccepted}, true}, {core.ChangeConfigurationConfirmation{Status: core.ConfigurationStatusRejected}, true}, @@ -32,11 +28,10 @@ func (suite *OcppV16TestSuite) TestChangeConfigurationConfirmationValidation() { {core.ChangeConfigurationConfirmation{Status: core.ConfigurationStatusNotSupported}, true}, {core.ChangeConfigurationConfirmation{Status: "invalidConfigurationStatus"}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestChangeConfigurationE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -51,27 +46,27 @@ func (suite *OcppV16TestSuite) TestChangeConfigurationE2EMocked() { coreListener := &MockChargePointCoreListener{} coreListener.On("OnChangeConfiguration", mock.Anything).Return(changeConfigurationConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*core.ChangeConfigurationRequest) - require.NotNil(t, request) - require.True(t, ok) - assert.Equal(t, key, request.Key) - assert.Equal(t, value, request.Value) + suite.Require().NotNil(request) + suite.Require().True(ok) + suite.Equal(key, request.Key) + suite.Equal(value, request.Value) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, coreListener, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.ChangeConfiguration(wsId, func(confirmation *core.ChangeConfigurationConfirmation, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, key, value) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestChangeConfigurationInvalidEndpoint() { diff --git a/ocpp1.6_test/clear_cache_test.go b/ocpp1.6_test/clear_cache_test.go index eb9b644a..e6cc994e 100644 --- a/ocpp1.6_test/clear_cache_test.go +++ b/ocpp1.6_test/clear_cache_test.go @@ -3,34 +3,29 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" ) // Test func (suite *OcppV16TestSuite) TestClearCacheRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {core.ClearCacheRequest{}, true}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestClearCacheConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {core.ClearCacheConfirmation{Status: core.ClearCacheStatusAccepted}, true}, {core.ClearCacheConfirmation{Status: core.ClearCacheStatusRejected}, true}, {core.ClearCacheConfirmation{Status: "invalidClearCacheStatus"}, false}, {core.ClearCacheConfirmation{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestClearCacheE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -47,17 +42,17 @@ func (suite *OcppV16TestSuite) TestClearCacheE2EMocked() { // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.ClearCache(wsId, func(confirmation *core.ClearCacheConfirmation, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestClearCacheInvalidEndpoint() { diff --git a/ocpp1.6_test/clear_charging_profile_test.go b/ocpp1.6_test/clear_charging_profile_test.go index 7cf49fd2..932e5dc2 100644 --- a/ocpp1.6_test/clear_charging_profile_test.go +++ b/ocpp1.6_test/clear_charging_profile_test.go @@ -3,16 +3,13 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Test func (suite *OcppV16TestSuite) TestClearChargingProfileRequestValidation() { - t := suite.T() requestTable := []GenericTestEntry{ {smartcharging.ClearChargingProfileRequest{Id: newInt(1), ConnectorId: newInt(1), ChargingProfilePurpose: types.ChargingProfilePurposeChargePointMaxProfile, StackLevel: newInt(1)}, true}, {smartcharging.ClearChargingProfileRequest{Id: newInt(1), ConnectorId: newInt(1), ChargingProfilePurpose: types.ChargingProfilePurposeChargePointMaxProfile}, true}, @@ -24,21 +21,19 @@ func (suite *OcppV16TestSuite) TestClearChargingProfileRequestValidation() { {smartcharging.ClearChargingProfileRequest{ChargingProfilePurpose: "invalidChargingProfilePurposeType"}, false}, {smartcharging.ClearChargingProfileRequest{StackLevel: newInt(-1)}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestClearChargingProfileConfirmationValidation() { - t := suite.T() confirmationTable := []GenericTestEntry{ {smartcharging.ClearChargingProfileConfirmation{Status: smartcharging.ClearChargingProfileStatusAccepted}, true}, {smartcharging.ClearChargingProfileConfirmation{Status: "invalidClearChargingProfileStatus"}, false}, {smartcharging.ClearChargingProfileConfirmation{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestClearChargingProfileE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -56,12 +51,12 @@ func (suite *OcppV16TestSuite) TestClearChargingProfileE2EMocked() { smartChargingListener := &MockChargePointSmartChargingListener{} smartChargingListener.On("OnClearChargingProfile", mock.Anything).Return(ClearChargingProfileConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*smartcharging.ClearChargingProfileRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, *chargingProfileId, *request.Id) - assert.Equal(t, *connectorId, *request.ConnectorId) - assert.Equal(t, chargingProfilePurpose, request.ChargingProfilePurpose) - assert.Equal(t, *stackLevel, *request.StackLevel) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(*chargingProfileId, *request.Id) + suite.Equal(*connectorId, *request.ConnectorId) + suite.Equal(chargingProfilePurpose, request.ChargingProfilePurpose) + suite.Equal(*stackLevel, *request.StackLevel) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, nil, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) @@ -69,12 +64,12 @@ func (suite *OcppV16TestSuite) TestClearChargingProfileE2EMocked() { // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - assert.Nil(t, err) + suite.Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.ClearChargingProfile(wsId, func(confirmation *smartcharging.ClearChargingProfileConfirmation, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, func(request *smartcharging.ClearChargingProfileRequest) { request.Id = chargingProfileId @@ -82,9 +77,9 @@ func (suite *OcppV16TestSuite) TestClearChargingProfileE2EMocked() { request.ChargingProfilePurpose = chargingProfilePurpose request.StackLevel = stackLevel }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestClearChargingProfileInvalidEndpoint() { diff --git a/ocpp1.6_test/common_test.go b/ocpp1.6_test/common_test.go index 92513d6a..fe8e4f14 100644 --- a/ocpp1.6_test/common_test.go +++ b/ocpp1.6_test/common_test.go @@ -7,7 +7,7 @@ import ( "github.com/relvacode/iso8601" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Utility functions @@ -33,11 +33,10 @@ func (suite *OcppV16TestSuite) TestIdTagInfoValidation() { {types.IdTagInfo{}, false}, {types.IdTagInfo{ExpiryDate: types.NewDateTime(time.Now()), ParentIdTag: ">20..................", Status: types.AuthorizationStatusAccepted}, false}, } - ExecuteGenericTestTable(suite.T(), testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV16TestSuite) TestChargingSchedulePeriodValidation() { - t := suite.T() testTable := []GenericTestEntry{ {types.ChargingSchedulePeriod{StartPeriod: 0, Limit: 10.0, NumberPhases: newInt(3)}, true}, {types.ChargingSchedulePeriod{StartPeriod: 0, Limit: 10.0}, true}, @@ -47,11 +46,10 @@ func (suite *OcppV16TestSuite) TestChargingSchedulePeriodValidation() { {types.ChargingSchedulePeriod{StartPeriod: -1, Limit: 10.0}, false}, {types.ChargingSchedulePeriod{StartPeriod: 0, Limit: 10.0, NumberPhases: newInt(-1)}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV16TestSuite) TestChargingScheduleValidation() { - t := suite.T() chargingSchedulePeriods := make([]types.ChargingSchedulePeriod, 2) chargingSchedulePeriods[0] = types.NewChargingSchedulePeriod(0, 10.0) chargingSchedulePeriods[1] = types.NewChargingSchedulePeriod(100, 8.0) @@ -66,11 +64,10 @@ func (suite *OcppV16TestSuite) TestChargingScheduleValidation() { {types.ChargingSchedule{Duration: newInt(0), StartSchedule: types.NewDateTime(time.Now()), ChargingRateUnit: types.ChargingRateUnitWatts, ChargingSchedulePeriod: make([]types.ChargingSchedulePeriod, 0), MinChargingRate: newFloat(1.0)}, false}, {types.ChargingSchedule{Duration: newInt(0), StartSchedule: types.NewDateTime(time.Now()), ChargingRateUnit: "invalidChargeRateUnit", ChargingSchedulePeriod: chargingSchedulePeriods, MinChargingRate: newFloat(1.0)}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV16TestSuite) TestChargingProfileValidation() { - t := suite.T() chargingSchedule := types.NewChargingSchedule(types.ChargingRateUnitWatts, types.NewChargingSchedulePeriod(0, 10.0), types.NewChargingSchedulePeriod(100, 8.0)) testTable := []GenericTestEntry{ {types.ChargingProfile{ChargingProfileId: 1, TransactionId: 1, StackLevel: 1, ChargingProfilePurpose: types.ChargingProfilePurposeChargePointMaxProfile, ChargingProfileKind: types.ChargingProfileKindAbsolute, RecurrencyKind: types.RecurrencyKindDaily, ValidFrom: types.NewDateTime(time.Now()), ValidTo: types.NewDateTime(time.Now().Add(8 * time.Hour)), ChargingSchedule: chargingSchedule}, true}, @@ -86,11 +83,10 @@ func (suite *OcppV16TestSuite) TestChargingProfileValidation() { {types.ChargingProfile{ChargingProfileId: 1, StackLevel: 1, ChargingProfilePurpose: types.ChargingProfilePurposeChargePointMaxProfile, ChargingProfileKind: types.ChargingProfileKindAbsolute, RecurrencyKind: "invalidRecurrencyKind", ChargingSchedule: chargingSchedule}, false}, {types.ChargingProfile{ChargingProfileId: 1, StackLevel: 1, ChargingProfilePurpose: types.ChargingProfilePurposeChargePointMaxProfile, ChargingProfileKind: types.ChargingProfileKindAbsolute, ChargingSchedule: types.NewChargingSchedule(types.ChargingRateUnitWatts)}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV16TestSuite) TestSampledValueValidation() { - t := suite.T() testTable := []GenericTestEntry{ {types.SampledValue{Value: "value", Context: types.ReadingContextTransactionEnd, Format: types.ValueFormatRaw, Measurand: types.MeasurandPowerActiveExport, Phase: types.PhaseL2, Location: types.LocationBody, Unit: types.UnitOfMeasureKW}, true}, {types.SampledValue{Value: "value", Context: types.ReadingContextTransactionEnd, Format: types.ValueFormatRaw, Measurand: types.MeasurandPowerActiveExport, Phase: types.PhaseL2, Location: types.LocationBody}, true}, @@ -106,7 +102,7 @@ func (suite *OcppV16TestSuite) TestSampledValueValidation() { {types.SampledValue{Value: "value", Location: "invalidLocation"}, false}, {types.SampledValue{Value: "value", Unit: "invalidUnit"}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV16TestSuite) TestMeterValueValidation() { @@ -117,7 +113,7 @@ func (suite *OcppV16TestSuite) TestMeterValueValidation() { {types.MeterValue{Timestamp: types.NewDateTime(time.Now())}, false}, {types.MeterValue{SampledValue: []types.SampledValue{{Value: "value"}}}, false}, } - ExecuteGenericTestTable(suite.T(), testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV16TestSuite) TestUnmarshalDateTime() { diff --git a/ocpp1.6_test/data_transfer_test.go b/ocpp1.6_test/data_transfer_test.go index 319b530d..850f509b 100644 --- a/ocpp1.6_test/data_transfer_test.go +++ b/ocpp1.6_test/data_transfer_test.go @@ -4,10 +4,8 @@ import ( "encoding/json" "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" ) type CustomData struct { @@ -24,7 +22,6 @@ func parseCustomData(req *core.DataTransferRequest) (CustomData, error) { // Test func (suite *OcppV16TestSuite) TestDataTransferRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {core.DataTransferRequest{VendorId: "12345"}, true}, {core.DataTransferRequest{VendorId: "12345", MessageId: "6789"}, true}, @@ -33,11 +30,10 @@ func (suite *OcppV16TestSuite) TestDataTransferRequestValidation() { {core.DataTransferRequest{VendorId: ">255............................................................................................................................................................................................................................................................"}, false}, {core.DataTransferRequest{VendorId: "12345", MessageId: ">50................................................"}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestDataTransferConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {core.DataTransferConfirmation{Status: core.DataTransferStatusAccepted}, true}, {core.DataTransferConfirmation{Status: core.DataTransferStatusRejected}, true}, @@ -46,11 +42,10 @@ func (suite *OcppV16TestSuite) TestDataTransferConfirmationValidation() { {core.DataTransferConfirmation{Status: "invalidDataTransferStatus"}, false}, {core.DataTransferConfirmation{Status: core.DataTransferStatusAccepted, Data: "mockData"}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestDataTransferFromChargePointE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -65,32 +60,31 @@ func (suite *OcppV16TestSuite) TestDataTransferFromChargePointE2EMocked() { coreListener := &MockCentralSystemCoreListener{} coreListener.On("OnDataTransfer", mock.AnythingOfType("string"), mock.Anything).Return(dataTransferConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*core.DataTransferRequest) - require.NotNil(t, request) - require.True(t, ok) - assert.Equal(t, vendorId, request.VendorId) - require.NotNil(t, request.Data) + suite.Require().NotNil(request) + suite.Require().True(ok) + suite.Equal(vendorId, request.VendorId) + suite.Require().NotNil(request.Data) customData, err := parseCustomData(request) - require.Nil(t, err) - require.NotNil(t, customData) - assert.Equal(t, data.Field1, customData.Field1) - assert.Equal(t, data.Field2, customData.Field2) + suite.Require().Nil(err) + suite.Require().NotNil(customData) + suite.Equal(data.Field1, customData.Field1) + suite.Equal(data.Field2, customData.Field2) }) setupDefaultCentralSystemHandlers(suite, coreListener, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, nil, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) confirmation, err := suite.chargePoint.DataTransfer(vendorId, func(request *core.DataTransferRequest) { request.Data = data }) - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) } func (suite *OcppV16TestSuite) TestDataTransferFromCentralSystemE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -105,32 +99,32 @@ func (suite *OcppV16TestSuite) TestDataTransferFromCentralSystemE2EMocked() { coreListener := &MockChargePointCoreListener{} coreListener.On("OnDataTransfer", mock.Anything).Return(dataTransferConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*core.DataTransferRequest) - require.NotNil(t, request) - require.True(t, ok) - assert.Equal(t, vendorId, request.VendorId) - require.NotNil(t, request.Data) + suite.Require().NotNil(request) + suite.Require().True(ok) + suite.Equal(vendorId, request.VendorId) + suite.Require().NotNil(request.Data) customData, err := parseCustomData(request) - require.Nil(t, err) - require.NotNil(t, customData) - assert.Equal(t, data.Field1, customData.Field1) - assert.Equal(t, data.Field2, customData.Field2) + suite.Require().Nil(err) + suite.Require().NotNil(customData) + suite.Equal(data.Field1, customData.Field1) + suite.Equal(data.Field2, customData.Field2) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, coreListener, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.DataTransfer(wsId, func(confirmation *core.DataTransferConfirmation, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, vendorId, func(request *core.DataTransferRequest) { request.Data = data }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } diff --git a/ocpp1.6_test/delete_certificate_test.go b/ocpp1.6_test/delete_certificate_test.go index 7cdfb80c..483423f5 100644 --- a/ocpp1.6_test/delete_certificate_test.go +++ b/ocpp1.6_test/delete_certificate_test.go @@ -3,27 +3,23 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/certificates" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/lorenzodonini/ocpp-go/ocpp1.6_test/mocks" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/certificates" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6_test/mocks" ) // Test func (suite *OcppV16TestSuite) TestDeleteCertificateRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {certificates.DeleteCertificateRequest{CertificateHashData: types.CertificateHashData{HashAlgorithm: types.SHA256, IssuerNameHash: "hash00", IssuerKeyHash: "hash01", SerialNumber: "serial0"}}, true}, {certificates.DeleteCertificateRequest{}, false}, {certificates.DeleteCertificateRequest{CertificateHashData: types.CertificateHashData{HashAlgorithm: "invalidHashAlgorithm", IssuerNameHash: "hash00", IssuerKeyHash: "hash01", SerialNumber: "serial0"}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestDeleteCertificateConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {certificates.DeleteCertificateResponse{Status: certificates.DeleteCertificateStatusAccepted}, true}, {certificates.DeleteCertificateResponse{Status: certificates.DeleteCertificateStatusFailed}, true}, @@ -31,7 +27,7 @@ func (suite *OcppV16TestSuite) TestDeleteCertificateConfirmationValidation() { {certificates.DeleteCertificateResponse{Status: "invalidDeleteCertificateStatus"}, false}, {certificates.DeleteCertificateResponse{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestDeleteCertificateE2EMocked() { @@ -49,10 +45,10 @@ func (suite *OcppV16TestSuite) TestDeleteCertificateE2EMocked() { handler := mocks.NewMockCertificatesChargePointHandler(t) handler.EXPECT().OnDeleteCertificate(mock.Anything).RunAndReturn(func(request *certificates.DeleteCertificateRequest) (*certificates.DeleteCertificateResponse, error) { - assert.Equal(t, certificateHashData.HashAlgorithm, request.CertificateHashData.HashAlgorithm) - assert.Equal(t, certificateHashData.IssuerNameHash, request.CertificateHashData.IssuerNameHash) - assert.Equal(t, certificateHashData.IssuerKeyHash, request.CertificateHashData.IssuerKeyHash) - assert.Equal(t, certificateHashData.SerialNumber, request.CertificateHashData.SerialNumber) + suite.Equal(certificateHashData.HashAlgorithm, request.CertificateHashData.HashAlgorithm) + suite.Equal(certificateHashData.IssuerNameHash, request.CertificateHashData.IssuerNameHash) + suite.Equal(certificateHashData.IssuerKeyHash, request.CertificateHashData.IssuerKeyHash) + suite.Equal(certificateHashData.SerialNumber, request.CertificateHashData.SerialNumber) return deleteCertificateConfirmation, nil }) @@ -63,19 +59,19 @@ func (suite *OcppV16TestSuite) TestDeleteCertificateE2EMocked() { // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.DeleteCertificate(wsId, func(confirmation *certificates.DeleteCertificateResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, certificateHashData) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestDeleteCertificateInvalidEndpoint() { diff --git a/ocpp1.6_test/diagnostics_status_notification_test.go b/ocpp1.6_test/diagnostics_status_notification_test.go index 8474f817..01c33760 100644 --- a/ocpp1.6_test/diagnostics_status_notification_test.go +++ b/ocpp1.6_test/diagnostics_status_notification_test.go @@ -3,33 +3,28 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" ) // Test func (suite *OcppV16TestSuite) TestDiagnosticsStatusNotificationRequestValidation() { - t := suite.T() requestTable := []GenericTestEntry{ {firmware.DiagnosticsStatusNotificationRequest{Status: firmware.DiagnosticsStatusUploaded}, true}, {firmware.DiagnosticsStatusNotificationRequest{}, false}, {firmware.DiagnosticsStatusNotificationRequest{Status: "invalidDiagnosticsStatus"}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestDiagnosticsStatusNotificationConfirmationValidation() { - t := suite.T() confirmationTable := []GenericTestEntry{ {firmware.DiagnosticsStatusNotificationConfirmation{}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestDiagnosticsStatusNotificationE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -42,9 +37,9 @@ func (suite *OcppV16TestSuite) TestDiagnosticsStatusNotificationE2EMocked() { firmwareListener := &MockCentralSystemFirmwareManagementListener{} firmwareListener.On("OnDiagnosticsStatusNotification", mock.AnythingOfType("string"), mock.Anything).Return(diagnosticsStatusNotificationConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*firmware.DiagnosticsStatusNotificationRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, status, request.Status) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(status, request.Status) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) suite.centralSystem.SetFirmwareManagementHandler(firmwareListener) @@ -52,10 +47,10 @@ func (suite *OcppV16TestSuite) TestDiagnosticsStatusNotificationE2EMocked() { // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) confirmation, err := suite.chargePoint.DiagnosticsStatusNotification(status) - require.Nil(t, err) - require.NotNil(t, confirmation) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) } func (suite *OcppV16TestSuite) TestDiagnosticsStatusNotificationInvalidEndpoint() { diff --git a/ocpp1.6_test/firmware_status_notification_test.go b/ocpp1.6_test/firmware_status_notification_test.go index ac2323f0..931c50e4 100644 --- a/ocpp1.6_test/firmware_status_notification_test.go +++ b/ocpp1.6_test/firmware_status_notification_test.go @@ -3,33 +3,28 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" ) // Test func (suite *OcppV16TestSuite) TestFirmwareStatusNotificationRequestValidation() { - t := suite.T() requestTable := []GenericTestEntry{ {firmware.FirmwareStatusNotificationRequest{Status: firmware.FirmwareStatusDownloaded}, true}, {firmware.FirmwareStatusNotificationRequest{}, false}, {firmware.FirmwareStatusNotificationRequest{Status: "invalidFirmwareStatus"}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestFirmwareStatusNotificationConfirmationValidation() { - t := suite.T() confirmationTable := []GenericTestEntry{ {firmware.FirmwareStatusNotificationConfirmation{}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestFirmwareStatusNotificationE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -42,9 +37,9 @@ func (suite *OcppV16TestSuite) TestFirmwareStatusNotificationE2EMocked() { firmwareListener := &MockCentralSystemFirmwareManagementListener{} firmwareListener.On("OnFirmwareStatusNotification", mock.AnythingOfType("string"), mock.Anything).Return(firmwareStatusNotificationConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*firmware.FirmwareStatusNotificationRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, status, request.Status) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(status, request.Status) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) suite.centralSystem.SetFirmwareManagementHandler(firmwareListener) @@ -52,10 +47,10 @@ func (suite *OcppV16TestSuite) TestFirmwareStatusNotificationE2EMocked() { // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) confirmation, err := suite.chargePoint.FirmwareStatusNotification(status) - require.Nil(t, err) - require.NotNil(t, confirmation) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) } func (suite *OcppV16TestSuite) TestFirmwareStatusNotificationInvalidEndpoint() { diff --git a/ocpp1.6_test/get_composite_schedule_test.go b/ocpp1.6_test/get_composite_schedule_test.go index 54877d42..e5be5f21 100644 --- a/ocpp1.6_test/get_composite_schedule_test.go +++ b/ocpp1.6_test/get_composite_schedule_test.go @@ -4,16 +4,13 @@ import ( "fmt" "time" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Test func (suite *OcppV16TestSuite) TestGetCompositeScheduleRequestValidation() { - t := suite.T() requestTable := []GenericTestEntry{ {smartcharging.GetCompositeScheduleRequest{ConnectorId: 1, Duration: 600, ChargingRateUnit: types.ChargingRateUnitWatts}, true}, {smartcharging.GetCompositeScheduleRequest{ConnectorId: 1, Duration: 600}, true}, @@ -24,11 +21,10 @@ func (suite *OcppV16TestSuite) TestGetCompositeScheduleRequestValidation() { {smartcharging.GetCompositeScheduleRequest{ConnectorId: 1, Duration: -1, ChargingRateUnit: types.ChargingRateUnitWatts}, false}, {smartcharging.GetCompositeScheduleRequest{ConnectorId: 1, Duration: 600, ChargingRateUnit: "invalidChargingRateUnit"}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestGetCompositeScheduleConfirmationValidation() { - t := suite.T() chargingSchedule := types.NewChargingSchedule(types.ChargingRateUnitWatts, types.NewChargingSchedulePeriod(0, 10.0)) confirmationTable := []GenericTestEntry{ {smartcharging.GetCompositeScheduleConfirmation{Status: smartcharging.GetCompositeScheduleStatusAccepted, ConnectorId: newInt(1), ScheduleStart: types.NewDateTime(time.Now()), ChargingSchedule: chargingSchedule}, true}, @@ -41,11 +37,10 @@ func (suite *OcppV16TestSuite) TestGetCompositeScheduleConfirmationValidation() {smartcharging.GetCompositeScheduleConfirmation{Status: smartcharging.GetCompositeScheduleStatusAccepted, ConnectorId: newInt(-1)}, false}, {smartcharging.GetCompositeScheduleConfirmation{Status: smartcharging.GetCompositeScheduleStatusAccepted, ConnectorId: newInt(1), ChargingSchedule: types.NewChargingSchedule(types.ChargingRateUnitWatts)}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestGetCompositeScheduleE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -70,11 +65,11 @@ func (suite *OcppV16TestSuite) TestGetCompositeScheduleE2EMocked() { smartChargingListener := &MockChargePointSmartChargingListener{} smartChargingListener.On("OnGetCompositeSchedule", mock.Anything).Return(getCompositeScheduleConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*smartcharging.GetCompositeScheduleRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, connectorId, request.ConnectorId) - assert.Equal(t, duration, request.Duration) - assert.Equal(t, chargingRateUnit, request.ChargingRateUnit) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(connectorId, request.ConnectorId) + suite.Equal(duration, request.Duration) + suite.Equal(chargingRateUnit, request.ChargingRateUnit) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, nil, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) @@ -82,30 +77,30 @@ func (suite *OcppV16TestSuite) TestGetCompositeScheduleE2EMocked() { // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.GetCompositeSchedule(wsId, func(confirmation *smartcharging.GetCompositeScheduleConfirmation, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) - require.NotNil(t, confirmation.ConnectorId) - assert.Equal(t, connectorId, *confirmation.ConnectorId) - assert.Equal(t, scheduleStart.FormatTimestamp(), confirmation.ScheduleStart.FormatTimestamp()) - assert.Equal(t, chargingSchedule.ChargingRateUnit, confirmation.ChargingSchedule.ChargingRateUnit) - assert.Equal(t, chargingSchedule.Duration, confirmation.ChargingSchedule.Duration) - assert.Equal(t, chargingSchedule.MinChargingRate, confirmation.ChargingSchedule.MinChargingRate) - assert.Equal(t, chargingSchedule.StartSchedule, confirmation.ChargingSchedule.StartSchedule) - assert.Equal(t, 1, len(confirmation.ChargingSchedule.ChargingSchedulePeriod)) - assert.Equal(t, chargingSchedule.ChargingSchedulePeriod[0].StartPeriod, confirmation.ChargingSchedule.ChargingSchedulePeriod[0].StartPeriod) - assert.Equal(t, chargingSchedule.ChargingSchedulePeriod[0].Limit, confirmation.ChargingSchedule.ChargingSchedulePeriod[0].Limit) - assert.Equal(t, chargingSchedule.ChargingSchedulePeriod[0].NumberPhases, confirmation.ChargingSchedule.ChargingSchedulePeriod[0].NumberPhases) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) + suite.Require().NotNil(confirmation.ConnectorId) + suite.Equal(connectorId, *confirmation.ConnectorId) + suite.Equal(scheduleStart.FormatTimestamp(), confirmation.ScheduleStart.FormatTimestamp()) + suite.Equal(chargingSchedule.ChargingRateUnit, confirmation.ChargingSchedule.ChargingRateUnit) + suite.Equal(chargingSchedule.Duration, confirmation.ChargingSchedule.Duration) + suite.Equal(chargingSchedule.MinChargingRate, confirmation.ChargingSchedule.MinChargingRate) + suite.Equal(chargingSchedule.StartSchedule, confirmation.ChargingSchedule.StartSchedule) + suite.Equal(1, len(confirmation.ChargingSchedule.ChargingSchedulePeriod)) + suite.Equal(chargingSchedule.ChargingSchedulePeriod[0].StartPeriod, confirmation.ChargingSchedule.ChargingSchedulePeriod[0].StartPeriod) + suite.Equal(chargingSchedule.ChargingSchedulePeriod[0].Limit, confirmation.ChargingSchedule.ChargingSchedulePeriod[0].Limit) + suite.Equal(chargingSchedule.ChargingSchedulePeriod[0].NumberPhases, confirmation.ChargingSchedule.ChargingSchedulePeriod[0].NumberPhases) resultChannel <- true }, connectorId, duration, func(request *smartcharging.GetCompositeScheduleRequest) { request.ChargingRateUnit = chargingRateUnit }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestGetCompositeScheduleInvalidEndpoint() { diff --git a/ocpp1.6_test/get_configuration_test.go b/ocpp1.6_test/get_configuration_test.go index 5f8aac99..6da56499 100644 --- a/ocpp1.6_test/get_configuration_test.go +++ b/ocpp1.6_test/get_configuration_test.go @@ -3,15 +3,12 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" ) // Test func (suite *OcppV16TestSuite) TestGetConfigurationRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {core.GetConfigurationRequest{Key: []string{"key1", "key2"}}, true}, {core.GetConfigurationRequest{Key: []string{"key1", "key2", "key3", "key4", "key5", "key6"}}, true}, @@ -20,11 +17,10 @@ func (suite *OcppV16TestSuite) TestGetConfigurationRequestValidation() { {core.GetConfigurationRequest{Key: []string{}}, true}, {core.GetConfigurationRequest{Key: []string{">50................................................"}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestGetConfigurationConfirmationValidation() { - t := suite.T() value1 := "value1" value2 := "value2" longValue := ">500................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................." @@ -40,11 +36,10 @@ func (suite *OcppV16TestSuite) TestGetConfigurationConfirmationValidation() { //{ocpp16.GetConfigurationConfirmation{ConfigurationKey: []ocpp16.ConfigurationKey{{Key: "key1", Readonly: true, Value: "value1"}, {Key: "key1", Readonly: false, Value: "value2"}}}, false}, } //TODO: additional test cases TBD. See get_configuration.go - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestGetConfigurationE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -66,28 +61,28 @@ func (suite *OcppV16TestSuite) TestGetConfigurationE2EMocked() { coreListener := &MockChargePointCoreListener{} coreListener.On("OnGetConfiguration", mock.Anything).Return(getConfigurationConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*core.GetConfigurationRequest) - require.NotNil(t, request) - require.True(t, ok) - require.Len(t, request.Key, len(requestKeys)) - assert.Equal(t, requestKeys, request.Key) + suite.Require().NotNil(request) + suite.Require().True(ok) + suite.Require().Len(request.Key, len(requestKeys)) + suite.Equal(requestKeys, request.Key) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, coreListener, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - assert.Nil(t, err) + suite.Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.GetConfiguration(wsId, func(confirmation *core.GetConfigurationConfirmation, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, unknownKeys, confirmation.UnknownKey) - assert.Equal(t, resultKeys, confirmation.ConfigurationKey) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(unknownKeys, confirmation.UnknownKey) + suite.Equal(resultKeys, confirmation.ConfigurationKey) resultChannel <- true }, requestKeys) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestGetConfigurationInvalidEndpoint() { diff --git a/ocpp1.6_test/get_diagnostics_test.go b/ocpp1.6_test/get_diagnostics_test.go index e81faa80..14ddc27f 100644 --- a/ocpp1.6_test/get_diagnostics_test.go +++ b/ocpp1.6_test/get_diagnostics_test.go @@ -4,16 +4,13 @@ import ( "fmt" "time" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Test func (suite *OcppV16TestSuite) TestGetDiagnosticsRequestValidation() { - t := suite.T() requestTable := []GenericTestEntry{ {firmware.GetDiagnosticsRequest{Location: "ftp:some/path", Retries: newInt(10), RetryInterval: newInt(10), StartTime: types.NewDateTime(time.Now()), StopTime: types.NewDateTime(time.Now())}, true}, {firmware.GetDiagnosticsRequest{Location: "ftp:some/path", Retries: newInt(10), RetryInterval: newInt(10), StartTime: types.NewDateTime(time.Now())}, true}, @@ -25,22 +22,20 @@ func (suite *OcppV16TestSuite) TestGetDiagnosticsRequestValidation() { {firmware.GetDiagnosticsRequest{Location: "ftp:some/path", Retries: newInt(-1)}, false}, {firmware.GetDiagnosticsRequest{Location: "ftp:some/path", RetryInterval: newInt(-1)}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestGetDiagnosticsConfirmationValidation() { - t := suite.T() confirmationTable := []GenericTestEntry{ {firmware.GetDiagnosticsConfirmation{FileName: "someFileName"}, true}, {firmware.GetDiagnosticsConfirmation{FileName: ""}, true}, {firmware.GetDiagnosticsConfirmation{}, true}, {firmware.GetDiagnosticsConfirmation{FileName: ">255............................................................................................................................................................................................................................................................"}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestGetDiagnosticsE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -60,15 +55,15 @@ func (suite *OcppV16TestSuite) TestGetDiagnosticsE2EMocked() { firmwareListener := &MockChargePointFirmwareManagementListener{} firmwareListener.On("OnGetDiagnostics", mock.Anything).Return(getDiagnosticsConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*firmware.GetDiagnosticsRequest) - require.NotNil(t, request) - require.True(t, ok) - assert.Equal(t, location, request.Location) - require.NotNil(t, request.Retries) - assert.Equal(t, *retries, *request.Retries) - require.NotNil(t, request.RetryInterval) - assert.Equal(t, *retryInterval, *request.RetryInterval) - assertDateTimeEquality(t, *startTime, *request.StartTime) - assertDateTimeEquality(t, *stopTime, *request.StopTime) + suite.Require().NotNil(request) + suite.Require().True(ok) + suite.Equal(location, request.Location) + suite.Require().NotNil(request.Retries) + suite.Equal(*retries, *request.Retries) + suite.Require().NotNil(request.RetryInterval) + suite.Equal(*retryInterval, *request.RetryInterval) + assertDateTimeEquality(suite, *startTime, *request.StartTime) + assertDateTimeEquality(suite, *stopTime, *request.StopTime) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) suite.chargePoint.SetFirmwareManagementHandler(firmwareListener) @@ -76,12 +71,12 @@ func (suite *OcppV16TestSuite) TestGetDiagnosticsE2EMocked() { // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.GetDiagnostics(wsId, func(confirmation *firmware.GetDiagnosticsConfirmation, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, fileName, confirmation.FileName) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(fileName, confirmation.FileName) resultChannel <- true }, location, func(request *firmware.GetDiagnosticsRequest) { request.RetryInterval = retryInterval @@ -89,9 +84,9 @@ func (suite *OcppV16TestSuite) TestGetDiagnosticsE2EMocked() { request.StartTime = startTime request.StopTime = stopTime }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestGetDiagnosticsInvalidEndpoint() { diff --git a/ocpp1.6_test/get_installed_certificate_ids_test.go b/ocpp1.6_test/get_installed_certificate_ids_test.go index 36967b0c..8721712f 100644 --- a/ocpp1.6_test/get_installed_certificate_ids_test.go +++ b/ocpp1.6_test/get_installed_certificate_ids_test.go @@ -3,26 +3,22 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/certificates" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/lorenzodonini/ocpp-go/ocpp1.6_test/mocks" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/certificates" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6_test/mocks" ) func (suite *OcppV16TestSuite) TestGetInstalledCertificateIdsRequestValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {certificates.GetInstalledCertificateIdsRequest{CertificateType: types.CentralSystemRootCertificate}, true}, {certificates.GetInstalledCertificateIdsRequest{}, false}, {certificates.GetInstalledCertificateIdsRequest{CertificateType: "invalidCertificateUse"}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV16TestSuite) TestGetInstalledCertificateIdsConfirmationValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {certificates.GetInstalledCertificateIdsResponse{Status: certificates.GetInstalledCertificateStatusAccepted}, true}, {certificates.GetInstalledCertificateIdsResponse{Status: certificates.GetInstalledCertificateStatusNotFound}, true}, @@ -30,7 +26,7 @@ func (suite *OcppV16TestSuite) TestGetInstalledCertificateIdsConfirmationValidat {certificates.GetInstalledCertificateIdsResponse{}, false}, {certificates.GetInstalledCertificateIdsResponse{Status: "invalidGetInstalledCertificateStatus"}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } // Test @@ -51,7 +47,7 @@ func (suite *OcppV16TestSuite) TestGetInstalledCertificateIdsE2EMocked() { // Setting handlers handler := mocks.NewMockCertificatesChargePointHandler(t) handler.EXPECT().OnGetInstalledCertificateIds(mock.Anything).RunAndReturn(func(request *certificates.GetInstalledCertificateIdsRequest) (*certificates.GetInstalledCertificateIdsResponse, error) { - assert.Equal(t, certificateType, request.CertificateType) + suite.Equal(certificateType, request.CertificateType) return getInstalledCertificateIdsConfirmation, nil }) @@ -63,18 +59,18 @@ func (suite *OcppV16TestSuite) TestGetInstalledCertificateIdsE2EMocked() { suite.centralSystem.Start(8887, "somePath") suite.chargePoint.SetCertificateHandler(handler) err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.GetInstalledCertificateIds(wsId, func(confirmation *certificates.GetInstalledCertificateIdsResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, certificateType) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestGetInstalledCertificateIdsInvalidEndpoint() { diff --git a/ocpp1.6_test/get_local_list_version_test.go b/ocpp1.6_test/get_local_list_version_test.go index de988d22..bcc07d36 100644 --- a/ocpp1.6_test/get_local_list_version_test.go +++ b/ocpp1.6_test/get_local_list_version_test.go @@ -3,23 +3,19 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/localauth" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/localauth" ) // Test func (suite *OcppV16TestSuite) TestGetLocalListVersionRequestValidation() { - t := suite.T() requestTable := []GenericTestEntry{ {localauth.GetLocalListVersionRequest{}, true}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestGetLocalListVersionConfirmationValidation() { - t := suite.T() confirmationTable := []GenericTestEntry{ {localauth.GetLocalListVersionConfirmation{ListVersion: 1}, true}, {localauth.GetLocalListVersionConfirmation{ListVersion: 0}, true}, @@ -27,11 +23,10 @@ func (suite *OcppV16TestSuite) TestGetLocalListVersionConfirmationValidation() { {localauth.GetLocalListVersionConfirmation{ListVersion: -1}, true}, {localauth.GetLocalListVersionConfirmation{ListVersion: -2}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestGetLocalListVersionE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -44,8 +39,8 @@ func (suite *OcppV16TestSuite) TestGetLocalListVersionE2EMocked() { localAuthListListener := &MockChargePointLocalAuthListListener{} localAuthListListener.On("OnGetLocalListVersion", mock.Anything).Return(localListVersionConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*localauth.GetLocalListVersionRequest) - require.NotNil(t, request) - require.True(t, ok) + suite.Require().NotNil(request) + suite.Require().True(ok) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) suite.chargePoint.SetLocalAuthListHandler(localAuthListListener) @@ -53,17 +48,17 @@ func (suite *OcppV16TestSuite) TestGetLocalListVersionE2EMocked() { // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.GetLocalListVersion(wsId, func(confirmation *localauth.GetLocalListVersionConfirmation, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, listVersion, confirmation.ListVersion) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(listVersion, confirmation.ListVersion) resultChannel <- true }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestGetLocalListVersionInvalidEndpoint() { diff --git a/ocpp1.6_test/heartbeat_test.go b/ocpp1.6_test/heartbeat_test.go index 648f2480..7985f85a 100644 --- a/ocpp1.6_test/heartbeat_test.go +++ b/ocpp1.6_test/heartbeat_test.go @@ -4,32 +4,28 @@ import ( "fmt" "time" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Test func (suite *OcppV16TestSuite) TestHeartbeatRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {core.HeartbeatRequest{}, true}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestHeartbeatConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {core.HeartbeatConfirmation{CurrentTime: types.NewDateTime(time.Now())}, true}, {core.HeartbeatConfirmation{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestHeartbeatE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -42,19 +38,19 @@ func (suite *OcppV16TestSuite) TestHeartbeatE2EMocked() { coreListener := &MockCentralSystemCoreListener{} coreListener.On("OnHeartbeat", mock.AnythingOfType("string"), mock.Anything).Return(heartbeatConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*core.HeartbeatRequest) - require.NotNil(t, request) - require.True(t, ok) + suite.Require().NotNil(request) + suite.Require().True(ok) }) setupDefaultCentralSystemHandlers(suite, coreListener, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, nil, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) confirmation, err := suite.chargePoint.Heartbeat() - require.Nil(t, err) - require.NotNil(t, confirmation) - assertDateTimeEquality(t, *currentTime, *confirmation.CurrentTime) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + assertDateTimeEquality(suite, *currentTime, *confirmation.CurrentTime) } func (suite *OcppV16TestSuite) TestHeartbeatInvalidEndpoint() { diff --git a/ocpp1.6_test/install_certificate_test.go b/ocpp1.6_test/install_certificate_test.go index eca258c0..ff89a7de 100644 --- a/ocpp1.6_test/install_certificate_test.go +++ b/ocpp1.6_test/install_certificate_test.go @@ -3,16 +3,13 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/certificates" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/lorenzodonini/ocpp-go/ocpp1.6_test/mocks" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/certificates" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6_test/mocks" ) func (suite *OcppV16TestSuite) TestInstallCertificateRequestValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {certificates.InstallCertificateRequest{CertificateType: types.ManufacturerRootCertificate, Certificate: "0xdeadbeef"}, true}, {certificates.InstallCertificateRequest{CertificateType: types.ManufacturerRootCertificate}, false}, @@ -23,11 +20,10 @@ func (suite *OcppV16TestSuite) TestInstallCertificateRequestValidation() { {certificates.InstallCertificateRequest{CertificateType: "invalidCertificateUse", Certificate: "0xdeadbeef"}, false}, {certificates.InstallCertificateRequest{CertificateType: types.ManufacturerRootCertificate, Certificate: newLongString(5501)}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV16TestSuite) TestInstallCertificateConfirmationValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {certificates.InstallCertificateResponse{Status: certificates.CertificateStatusAccepted}, true}, {certificates.InstallCertificateResponse{Status: certificates.CertificateStatusRejected}, true}, @@ -35,7 +31,7 @@ func (suite *OcppV16TestSuite) TestInstallCertificateConfirmationValidation() { {certificates.InstallCertificateResponse{}, false}, {certificates.InstallCertificateResponse{Status: "invalidInstallCertificateStatus"}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } // Test @@ -55,8 +51,8 @@ func (suite *OcppV16TestSuite) TestInstallCertificateE2EMocked() { // Setting handlers handler := mocks.NewMockCertificatesChargePointHandler(t) handler.EXPECT().OnInstallCertificate(mock.Anything).RunAndReturn(func(request *certificates.InstallCertificateRequest) (*certificates.InstallCertificateResponse, error) { - assert.Equal(t, certificateType, request.CertificateType) - assert.Equal(t, certificate, request.Certificate) + suite.Equal(certificateType, request.CertificateType) + suite.Equal(certificate, request.Certificate) return installCertificateResponse, nil }) @@ -68,17 +64,17 @@ func (suite *OcppV16TestSuite) TestInstallCertificateE2EMocked() { suite.centralSystem.Start(8887, "somePath") suite.chargePoint.SetCertificateHandler(handler) err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.InstallCertificate(wsId, func(response *certificates.InstallCertificateResponse, err error) { - require.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, status, response.Status) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Equal(status, response.Status) resultChannel <- true }, certificateType, certificate) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestInstallCertificateInvalidEndpoint() { diff --git a/ocpp1.6_test/meter_values_test.go b/ocpp1.6_test/meter_values_test.go index e5792974..e436c2e2 100644 --- a/ocpp1.6_test/meter_values_test.go +++ b/ocpp1.6_test/meter_values_test.go @@ -4,11 +4,9 @@ import ( "fmt" "time" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Test @@ -22,18 +20,17 @@ func (suite *OcppV16TestSuite) TestMeterValuesRequestValidation() { {core.MeterValuesRequest{ConnectorId: 1}, false}, {core.MeterValuesRequest{ConnectorId: 1, MeterValue: []types.MeterValue{{Timestamp: types.NewDateTime(time.Now()), SampledValue: []types.SampledValue{}}}}, false}, } - ExecuteGenericTestTable(suite.T(), requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestMeterValuesConfirmationValidation() { var confirmationTable = []GenericTestEntry{ {core.MeterValuesConfirmation{}, true}, } - ExecuteGenericTestTable(suite.T(), confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestMeterValuesE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -50,26 +47,26 @@ func (suite *OcppV16TestSuite) TestMeterValuesE2EMocked() { coreListener := &MockCentralSystemCoreListener{} coreListener.On("OnMeterValues", mock.AnythingOfType("string"), mock.Anything).Return(meterValuesConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*core.MeterValuesRequest) - require.NotNil(t, request) - require.True(t, ok) - assert.Equal(t, connectorId, request.ConnectorId) - require.Equal(t, 1, len(request.MeterValue)) + suite.Require().NotNil(request) + suite.Require().True(ok) + suite.Equal(connectorId, request.ConnectorId) + suite.Require().Equal(1, len(request.MeterValue)) mv := request.MeterValue[0] - assertDateTimeEquality(t, timestamp, *mv.Timestamp) - require.Equal(t, 1, len(mv.SampledValue)) + assertDateTimeEquality(suite, timestamp, *mv.Timestamp) + suite.Require().Equal(1, len(mv.SampledValue)) sv := mv.SampledValue[0] - assert.Equal(t, mockValue, sv.Value) - assert.Equal(t, mockUnit, sv.Unit) + suite.Equal(mockValue, sv.Value) + suite.Equal(mockUnit, sv.Unit) }) setupDefaultCentralSystemHandlers(suite, coreListener, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, nil, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) confirmation, err := suite.chargePoint.MeterValues(connectorId, meterValues) - require.Nil(t, err) - require.NotNil(t, confirmation) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) } func (suite *OcppV16TestSuite) TestMeterValuesInvalidEndpoint() { diff --git a/ocpp1.6_test/mocks/mock_certificates_charge_point_handler.go b/ocpp1.6_test/mocks/mock_certificates_charge_point_handler.go index 363c4fde..a5efb7af 100644 --- a/ocpp1.6_test/mocks/mock_certificates_charge_point_handler.go +++ b/ocpp1.6_test/mocks/mock_certificates_charge_point_handler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - certificates "github.com/lorenzodonini/ocpp-go/ocpp1.6/certificates" mock "github.com/stretchr/testify/mock" + certificates "github.com/xBlaz3kx/ocpp-go/ocpp1.6/certificates" ) // MockCertificatesChargePointHandler is an autogenerated mock type for the ChargePointHandler type diff --git a/ocpp1.6_test/mocks/mock_core_central_system_handler.go b/ocpp1.6_test/mocks/mock_core_central_system_handler.go index 6aa1d683..4c9eea12 100644 --- a/ocpp1.6_test/mocks/mock_core_central_system_handler.go +++ b/ocpp1.6_test/mocks/mock_core_central_system_handler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - core "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" mock "github.com/stretchr/testify/mock" + core "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" ) // MockCoreCentralSystemHandler is an autogenerated mock type for the CentralSystemHandler type diff --git a/ocpp1.6_test/mocks/mock_core_charge_point_handler.go b/ocpp1.6_test/mocks/mock_core_charge_point_handler.go index 492865ef..680c05d4 100644 --- a/ocpp1.6_test/mocks/mock_core_charge_point_handler.go +++ b/ocpp1.6_test/mocks/mock_core_charge_point_handler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - core "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" mock "github.com/stretchr/testify/mock" + core "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" ) // MockCoreChargePointHandler is an autogenerated mock type for the ChargePointHandler type diff --git a/ocpp1.6_test/mocks/mock_extended_trigger_message_charge_point_handler.go b/ocpp1.6_test/mocks/mock_extended_trigger_message_charge_point_handler.go index 606a3412..21a46bc1 100644 --- a/ocpp1.6_test/mocks/mock_extended_trigger_message_charge_point_handler.go +++ b/ocpp1.6_test/mocks/mock_extended_trigger_message_charge_point_handler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - extendedtriggermessage "github.com/lorenzodonini/ocpp-go/ocpp1.6/extendedtriggermessage" mock "github.com/stretchr/testify/mock" + extendedtriggermessage "github.com/xBlaz3kx/ocpp-go/ocpp1.6/extendedtriggermessage" ) // MockExtendedTriggerMessageChargePointHandler is an autogenerated mock type for the ChargePointHandler type diff --git a/ocpp1.6_test/mocks/mock_firmware_central_system_handler.go b/ocpp1.6_test/mocks/mock_firmware_central_system_handler.go index 46583764..74259859 100644 --- a/ocpp1.6_test/mocks/mock_firmware_central_system_handler.go +++ b/ocpp1.6_test/mocks/mock_firmware_central_system_handler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - firmware "github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware" mock "github.com/stretchr/testify/mock" + firmware "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" ) // MockFirmwareCentralSystemHandler is an autogenerated mock type for the CentralSystemHandler type diff --git a/ocpp1.6_test/mocks/mock_firmware_charge_point_handler.go b/ocpp1.6_test/mocks/mock_firmware_charge_point_handler.go index 13f874ee..dd1f863d 100644 --- a/ocpp1.6_test/mocks/mock_firmware_charge_point_handler.go +++ b/ocpp1.6_test/mocks/mock_firmware_charge_point_handler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - firmware "github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware" mock "github.com/stretchr/testify/mock" + firmware "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" ) // MockFirmwareChargePointHandler is an autogenerated mock type for the ChargePointHandler type diff --git a/ocpp1.6_test/mocks/mock_local_auth_list_central_system_handler.go b/ocpp1.6_test/mocks/mock_local_auth_list_central_system_handler.go index 6da113c5..20092761 100644 --- a/ocpp1.6_test/mocks/mock_local_auth_list_central_system_handler.go +++ b/ocpp1.6_test/mocks/mock_local_auth_list_central_system_handler.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks diff --git a/ocpp1.6_test/mocks/mock_local_auth_list_charge_point_handler.go b/ocpp1.6_test/mocks/mock_local_auth_list_charge_point_handler.go index b7a552d6..dd3bafb2 100644 --- a/ocpp1.6_test/mocks/mock_local_auth_list_charge_point_handler.go +++ b/ocpp1.6_test/mocks/mock_local_auth_list_charge_point_handler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - localauth "github.com/lorenzodonini/ocpp-go/ocpp1.6/localauth" mock "github.com/stretchr/testify/mock" + localauth "github.com/xBlaz3kx/ocpp-go/ocpp1.6/localauth" ) // MockLocalAuthListChargePointHandler is an autogenerated mock type for the ChargePointHandler type diff --git a/ocpp1.6_test/mocks/mock_logging_central_system_handler.go b/ocpp1.6_test/mocks/mock_logging_central_system_handler.go index f8b0ed68..bdf97b16 100644 --- a/ocpp1.6_test/mocks/mock_logging_central_system_handler.go +++ b/ocpp1.6_test/mocks/mock_logging_central_system_handler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - logging "github.com/lorenzodonini/ocpp-go/ocpp1.6/logging" mock "github.com/stretchr/testify/mock" + logging "github.com/xBlaz3kx/ocpp-go/ocpp1.6/logging" ) // MockLogCentralSystemHandler is an autogenerated mock type for the CentralSystemHandler type diff --git a/ocpp1.6_test/mocks/mock_logging_charge_point_handler.go b/ocpp1.6_test/mocks/mock_logging_charge_point_handler.go index f26f5227..24546a82 100644 --- a/ocpp1.6_test/mocks/mock_logging_charge_point_handler.go +++ b/ocpp1.6_test/mocks/mock_logging_charge_point_handler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - logging "github.com/lorenzodonini/ocpp-go/ocpp1.6/logging" mock "github.com/stretchr/testify/mock" + logging "github.com/xBlaz3kx/ocpp-go/ocpp1.6/logging" ) // MockLogChargePointHandler is an autogenerated mock type for the ChargePointHandler type diff --git a/ocpp1.6_test/mocks/mock_ocpp16.go b/ocpp1.6_test/mocks/mock_ocpp16.go index 330eecee..64ed04bd 100644 --- a/ocpp1.6_test/mocks/mock_ocpp16.go +++ b/ocpp1.6_test/mocks/mock_ocpp16.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ocpp16 "github.com/lorenzodonini/ocpp-go/ocpp1.6" mock "github.com/stretchr/testify/mock" + ocpp16 "github.com/xBlaz3kx/ocpp-go/ocpp1.6" ) // MockChargePointConnectionHandler is an autogenerated mock type for the ChargePointConnectionHandler type diff --git a/ocpp1.6_test/mocks/mock_remote_trigger_central_system_handler.go b/ocpp1.6_test/mocks/mock_remote_trigger_central_system_handler.go index 1d95ec5e..49bc1216 100644 --- a/ocpp1.6_test/mocks/mock_remote_trigger_central_system_handler.go +++ b/ocpp1.6_test/mocks/mock_remote_trigger_central_system_handler.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks diff --git a/ocpp1.6_test/mocks/mock_remote_trigger_charge_point_handler.go b/ocpp1.6_test/mocks/mock_remote_trigger_charge_point_handler.go index ae0d35d1..51fbf5cd 100644 --- a/ocpp1.6_test/mocks/mock_remote_trigger_charge_point_handler.go +++ b/ocpp1.6_test/mocks/mock_remote_trigger_charge_point_handler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - remotetrigger "github.com/lorenzodonini/ocpp-go/ocpp1.6/remotetrigger" mock "github.com/stretchr/testify/mock" + remotetrigger "github.com/xBlaz3kx/ocpp-go/ocpp1.6/remotetrigger" ) // MockRemoteTriggerChargePointHandler is an autogenerated mock type for the ChargePointHandler type diff --git a/ocpp1.6_test/mocks/mock_reservation_central_system_handler.go b/ocpp1.6_test/mocks/mock_reservation_central_system_handler.go index 7ce97b06..ebf8e53d 100644 --- a/ocpp1.6_test/mocks/mock_reservation_central_system_handler.go +++ b/ocpp1.6_test/mocks/mock_reservation_central_system_handler.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks diff --git a/ocpp1.6_test/mocks/mock_reservation_charge_point_handler.go b/ocpp1.6_test/mocks/mock_reservation_charge_point_handler.go index 2800b719..2539f4f8 100644 --- a/ocpp1.6_test/mocks/mock_reservation_charge_point_handler.go +++ b/ocpp1.6_test/mocks/mock_reservation_charge_point_handler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - reservation "github.com/lorenzodonini/ocpp-go/ocpp1.6/reservation" mock "github.com/stretchr/testify/mock" + reservation "github.com/xBlaz3kx/ocpp-go/ocpp1.6/reservation" ) // MockReservationChargePointHandler is an autogenerated mock type for the ChargePointHandler type diff --git a/ocpp1.6_test/mocks/mock_secure_firmware_CentralSystemHandler.go b/ocpp1.6_test/mocks/mock_secure_firmware_CentralSystemHandler.go index a8540226..0c8defcd 100644 --- a/ocpp1.6_test/mocks/mock_secure_firmware_CentralSystemHandler.go +++ b/ocpp1.6_test/mocks/mock_secure_firmware_CentralSystemHandler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - securefirmware "github.com/lorenzodonini/ocpp-go/ocpp1.6/securefirmware" mock "github.com/stretchr/testify/mock" + securefirmware "github.com/xBlaz3kx/ocpp-go/ocpp1.6/securefirmware" ) // MockSecureFirmwareCentralSystemHandler is an autogenerated mock type for the CentralSystemHandler type diff --git a/ocpp1.6_test/mocks/mock_secure_firmware_ChargePointHandler.go b/ocpp1.6_test/mocks/mock_secure_firmware_ChargePointHandler.go index fbede0a3..4af1a372 100644 --- a/ocpp1.6_test/mocks/mock_secure_firmware_ChargePointHandler.go +++ b/ocpp1.6_test/mocks/mock_secure_firmware_ChargePointHandler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - securefirmware "github.com/lorenzodonini/ocpp-go/ocpp1.6/securefirmware" mock "github.com/stretchr/testify/mock" + securefirmware "github.com/xBlaz3kx/ocpp-go/ocpp1.6/securefirmware" ) // MockSecureFirmwareChargePointHandler is an autogenerated mock type for the ChargePointHandler type diff --git a/ocpp1.6_test/mocks/mock_security_central_system_handler.go b/ocpp1.6_test/mocks/mock_security_central_system_handler.go index 3728fadc..194c3e16 100644 --- a/ocpp1.6_test/mocks/mock_security_central_system_handler.go +++ b/ocpp1.6_test/mocks/mock_security_central_system_handler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - security "github.com/lorenzodonini/ocpp-go/ocpp1.6/security" mock "github.com/stretchr/testify/mock" + security "github.com/xBlaz3kx/ocpp-go/ocpp1.6/security" ) // MockSecurityCentralSystemHandler is an autogenerated mock type for the CentralSystemHandler type diff --git a/ocpp1.6_test/mocks/mock_security_charge_point_handler.go b/ocpp1.6_test/mocks/mock_security_charge_point_handler.go index 012adec9..d6002d03 100644 --- a/ocpp1.6_test/mocks/mock_security_charge_point_handler.go +++ b/ocpp1.6_test/mocks/mock_security_charge_point_handler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - security "github.com/lorenzodonini/ocpp-go/ocpp1.6/security" mock "github.com/stretchr/testify/mock" + security "github.com/xBlaz3kx/ocpp-go/ocpp1.6/security" ) // MockSecurityChargePointHandler is an autogenerated mock type for the ChargePointHandler type diff --git a/ocpp1.6_test/mocks/mock_smart_charging_central_system_handler.go b/ocpp1.6_test/mocks/mock_smart_charging_central_system_handler.go index 1a5ebb75..95c9ec09 100644 --- a/ocpp1.6_test/mocks/mock_smart_charging_central_system_handler.go +++ b/ocpp1.6_test/mocks/mock_smart_charging_central_system_handler.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks diff --git a/ocpp1.6_test/mocks/mock_smart_charging_charge_point_handler.go b/ocpp1.6_test/mocks/mock_smart_charging_charge_point_handler.go index 61ee69cd..adbfaf78 100644 --- a/ocpp1.6_test/mocks/mock_smart_charging_charge_point_handler.go +++ b/ocpp1.6_test/mocks/mock_smart_charging_charge_point_handler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - smartcharging "github.com/lorenzodonini/ocpp-go/ocpp1.6/smartcharging" mock "github.com/stretchr/testify/mock" + smartcharging "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" ) // MockSmartChargingChargePointHandler is an autogenerated mock type for the ChargePointHandler type diff --git a/ocpp1.6_test/ocpp16_test.go b/ocpp1.6_test/ocpp16_test.go index a46ee6ee..3d32b842 100644 --- a/ocpp1.6_test/ocpp16_test.go +++ b/ocpp1.6_test/ocpp16_test.go @@ -8,25 +8,24 @@ import ( "testing" "time" - "github.com/lorenzodonini/ocpp-go/ocpp" - ocpp16 "github.com/lorenzodonini/ocpp-go/ocpp1.6" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/certificates" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/extendedtriggermessage" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/remotetrigger" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/securefirmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/security" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/lorenzodonini/ocpp-go/ocppj" - "github.com/lorenzodonini/ocpp-go/ws" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "github.com/xBlaz3kx/ocpp-go/ocpp" + ocpp16 "github.com/xBlaz3kx/ocpp-go/ocpp1.6" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/certificates" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/extendedtriggermessage" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/remotetrigger" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/securefirmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/security" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ws" + "go.opentelemetry.io/otel/metric/noop" ) // ---------------------- MOCK WEBSOCKET ---------------------- @@ -468,9 +467,8 @@ type expectedChargePointOptions struct { } func setupDefaultCentralSystemHandlers(suite *OcppV16TestSuite, coreListener core.CentralSystemHandler, options expectedCentralSystemOptions) { - t := suite.T() suite.centralSystem.SetNewChargePointHandler(func(chargePoint ocpp16.ChargePointConnection) { - assert.Equal(t, options.clientId, chargePoint.ID()) + suite.Equal(options.clientId, chargePoint.ID()) }) suite.centralSystem.SetCoreHandler(coreListener) suite.mockWsServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(options.startReturnArgument) @@ -479,25 +477,24 @@ func setupDefaultCentralSystemHandlers(suite *OcppV16TestSuite, coreListener cor clientId := args.String(0) data := args.Get(1) bytes := data.([]byte) - assert.Equal(t, options.clientId, clientId) + suite.Equal(options.clientId, clientId) if options.rawWrittenMessage != nil { - assert.NotNil(t, bytes) - assert.Equal(t, options.rawWrittenMessage, bytes) + suite.NotNil(bytes) + suite.Equal(options.rawWrittenMessage, bytes) } if options.forwardWrittenMessage { // Notify client of incoming response err := suite.mockWsClient.MessageHandler(bytes) - assert.Nil(t, err) + suite.Nil(err) } }) } func setupDefaultChargePointHandlers(suite *OcppV16TestSuite, coreListener core.ChargePointHandler, options expectedChargePointOptions) { - t := suite.T() suite.chargePoint.SetCoreHandler(coreListener) suite.mockWsClient.On("Start", mock.AnythingOfType("string")).Return(options.startReturnArgument).Run(func(args mock.Arguments) { u := args.String(0) - assert.Equal(t, fmt.Sprintf("%s/%s", options.serverUrl, options.clientId), u) + suite.Equal(fmt.Sprintf("%s/%s", options.serverUrl, options.clientId), u) // Notify server of incoming connection if options.createChannelOnStart { suite.mockWsServer.NewClientHandler(options.channel) @@ -507,19 +504,19 @@ func setupDefaultChargePointHandlers(suite *OcppV16TestSuite, coreListener core. data := args.Get(0) bytes := data.([]byte) if options.rawWrittenMessage != nil { - assert.NotNil(t, bytes) - assert.Equal(t, options.rawWrittenMessage, bytes) + suite.NotNil(bytes) + suite.Equal(options.rawWrittenMessage, bytes) } // Notify server of incoming request if options.forwardWrittenMessage { err := suite.mockWsServer.MessageHandler(options.channel, bytes) - assert.Nil(t, err) + suite.Nil(err) } }) } -func assertDateTimeEquality(t *testing.T, expected types.DateTime, actual types.DateTime) { - assert.Equal(t, expected.FormatTimestamp(), actual.FormatTimestamp()) +func assertDateTimeEquality(suite *OcppV16TestSuite, expected types.DateTime, actual types.DateTime) { + suite.Equal(expected.FormatTimestamp(), actual.FormatTimestamp()) } func testUnsupportedRequestFromChargePoint(suite *OcppV16TestSuite, request ocpp.Request, requestJson string, messageId string) { @@ -536,29 +533,29 @@ func testUnsupportedRequestFromChargePoint(suite *OcppV16TestSuite, request ocpp setupDefaultCentralSystemHandlers(suite, coreListener, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(errorJson), forwardWrittenMessage: true}) resultChannel := make(chan struct{}, 1) suite.ocppjChargePoint.SetErrorHandler(func(err *ocpp.Error, details interface{}) { - assert.Equal(t, messageId, err.MessageId) - assert.Equal(t, ocppj.NotSupported, err.Code) - assert.Equal(t, errorDescription, err.Description) - assert.Equal(t, map[string]interface{}{}, details) + suite.Equal(messageId, err.MessageId) + suite.Equal(ocppj.NotSupported, err.Code) + suite.Equal(errorDescription, err.Description) + suite.Equal(map[string]interface{}{}, details) resultChannel <- struct{}{} }) // Start suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) // 1. Test sending an unsupported request, expecting an error err = suite.chargePoint.SendRequestAsync(request, func(confirmation ocpp.Response, err error) { t.Fail() }) - require.Error(t, err) - assert.Equal(t, expectedError, err.Error()) + suite.Require().Error(err) + suite.Equal(expectedError, err.Error()) // 2. Test receiving an unsupported request on the other endpoint and receiving an error // Mark mocked request as pending, otherwise response will be ignored suite.ocppjChargePoint.RequestState.AddPendingRequest(messageId, request) err = suite.mockWsServer.MessageHandler(channel, []byte(requestJson)) - assert.Nil(t, err) + suite.Nil(err) _, ok := <-resultChannel - assert.True(t, ok) + suite.True(ok) // Stop the central system suite.centralSystem.Stop() } @@ -577,30 +574,30 @@ func testUnsupportedRequestFromCentralSystem(suite *OcppV16TestSuite, request oc setupDefaultChargePointHandlers(suite, coreListener, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(errorJson), forwardWrittenMessage: true}) resultChannel := make(chan struct{}, 1) suite.ocppjCentralSystem.SetErrorHandler(func(chargePoint ws.Channel, err *ocpp.Error, details interface{}) { - assert.Equal(t, messageId, err.MessageId) - assert.Equal(t, wsId, chargePoint.ID()) - assert.Equal(t, ocppj.NotSupported, err.Code) - assert.Equal(t, errorDescription, err.Description) - assert.Equal(t, map[string]interface{}{}, details) + suite.Equal(messageId, err.MessageId) + suite.Equal(wsId, chargePoint.ID()) + suite.Equal(ocppj.NotSupported, err.Code) + suite.Equal(errorDescription, err.Description) + suite.Equal(map[string]interface{}{}, details) resultChannel <- struct{}{} }) // Start suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) // 1. Test sending an unsupported request, expecting an error err = suite.centralSystem.SendRequestAsync(wsId, request, func(confirmation ocpp.Response, err error) { t.Fail() }) - require.Error(t, err) - assert.Equal(t, expectedError, err.Error()) + suite.Require().Error(err) + suite.Equal(expectedError, err.Error()) // 2. Test receiving an unsupported request on the other endpoint and receiving an error // Mark mocked request as pending, otherwise response will be ignored suite.ocppjCentralSystem.RequestState.AddPendingRequest(wsId, messageId, request) err = suite.mockWsClient.MessageHandler([]byte(requestJson)) - assert.Nil(t, err) + suite.Nil(err) _, ok := <-resultChannel - assert.True(t, ok) + suite.True(ok) // Stop the central system suite.centralSystem.Stop() } @@ -621,13 +618,13 @@ type ConfirmationTestEntry struct { } // TODO: pass expected error value for improved validation and error message -func ExecuteGenericTestTable(t *testing.T, testTable []GenericTestEntry) { +func ExecuteGenericTestTable(suite *OcppV16TestSuite, testTable []GenericTestEntry) { for _, testCase := range testTable { err := types.Validate.Struct(testCase.Element) if err != nil { - assert.Equal(t, testCase.ExpectedValid, false, err.Error()) + suite.Equal(false, testCase.ExpectedValid, err.Error()) } else { - assert.Equal(t, testCase.ExpectedValid, true, "%v is valid", testCase.Element) + suite.Equal(true, testCase.ExpectedValid, "%v is valid", testCase.Element) } } } @@ -669,15 +666,17 @@ func (suite *OcppV16TestSuite) SetupTest() { securityProfile := security.Profile mockClient := MockWebsocketClient{} mockServer := MockWebsocketServer{} + var err error suite.mockWsClient = &mockClient suite.mockWsServer = &mockServer - suite.clientDispatcher = ocppj.NewDefaultClientDispatcher(ocppj.NewFIFOClientQueue(queueCapacity)) - suite.serverDispatcher = ocppj.NewDefaultServerDispatcher(ocppj.NewFIFOQueueMap(queueCapacity)) - suite.ocppjChargePoint = ocppj.NewClient( + suite.clientDispatcher = ocppj.NewDefaultClientDispatcher(ocppj.NewFIFOClientQueue(queueCapacity), nil) + suite.serverDispatcher = ocppj.NewDefaultServerDispatcher(ocppj.NewFIFOQueueMap(queueCapacity), noop.NewMeterProvider(), nil) + suite.ocppjChargePoint, err = ocppj.NewClient( "test_id", suite.mockWsClient, suite.clientDispatcher, nil, + nil, coreProfile, localAuthListProfile, firmwareProfile, @@ -689,10 +688,12 @@ func (suite *OcppV16TestSuite) SetupTest() { securityProfile, secureFirmwareUpdateProfile, ) - suite.ocppjCentralSystem = ocppj.NewServer( + suite.Require().NoError(err) + suite.ocppjCentralSystem, err = ocppj.NewServer( suite.mockWsServer, suite.serverDispatcher, nil, + nil, coreProfile, localAuthListProfile, firmwareProfile, @@ -704,8 +705,11 @@ func (suite *OcppV16TestSuite) SetupTest() { securityProfile, secureFirmwareUpdateProfile, ) - suite.chargePoint = ocpp16.NewChargePoint("test_id", suite.ocppjChargePoint, suite.mockWsClient) - suite.centralSystem = ocpp16.NewCentralSystem(suite.ocppjCentralSystem, suite.mockWsServer) + suite.Require().NoError(err) + suite.chargePoint, err = ocpp16.NewChargePoint("test_id", suite.ocppjChargePoint, suite.mockWsClient, nil) + suite.Require().NoError(err) + suite.centralSystem, err = ocpp16.NewCentralSystem(suite.ocppjCentralSystem, suite.mockWsServer, nil) + suite.Require().NoError(err) suite.messageIdGenerator = TestRandomIdGenerator{generator: func() string { return defaultMessageId }} @@ -714,13 +718,12 @@ func (suite *OcppV16TestSuite) SetupTest() { } func (suite *OcppV16TestSuite) TestIsConnected() { - t := suite.T() // Simulate ws connected mockCall := suite.mockWsClient.On("IsConnected").Return(true) - assert.True(t, suite.chargePoint.IsConnected()) + suite.True(suite.chargePoint.IsConnected()) // Simulate ws disconnected mockCall.Return(false) - assert.False(t, suite.chargePoint.IsConnected()) + suite.False(suite.chargePoint.IsConnected()) } // TODO: implement generic protocol tests diff --git a/ocpp1.6_test/proto_test.go b/ocpp1.6_test/proto_test.go index bccbae92..ec5a5333 100644 --- a/ocpp1.6_test/proto_test.go +++ b/ocpp1.6_test/proto_test.go @@ -4,12 +4,10 @@ import ( "fmt" "testing" - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocppj" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocppj" ) func (suite *OcppV16TestSuite) TestChargePointSendResponseError() { @@ -28,19 +26,19 @@ func (suite *OcppV16TestSuite) TestChargePointSendResponseError() { rawMsg := args.Get(0) bytes := rawMsg.([]byte) err := suite.mockWsServer.MessageHandler(channel, bytes) - assert.Nil(t, err) + suite.Nil(err) }) suite.mockWsServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) suite.mockWsServer.On("Write", mock.AnythingOfType("string"), mock.Anything).Return(nil).Run(func(args mock.Arguments) { rawMsg := args.Get(1) bytes := rawMsg.([]byte) err := suite.mockWsClient.MessageHandler(bytes) - assert.NoError(t, err) + suite.NoError(err) }) // Run Tests suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start("someUrl") - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan error, 1) testCases := []struct { @@ -77,22 +75,21 @@ func (suite *OcppV16TestSuite) TestChargePointSendResponseError() { } err = suite.centralSystem.DataTransfer(wsId, func(confirmation *core.DataTransferConfirmation, err error) { - require.Nil(t, confirmation) - require.Error(t, err) + suite.Require().Nil(confirmation) + suite.Require().Error(err) resultChannel <- err }, "vendor1") - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - require.IsType(t, &ocpp.Error{}, result) + suite.Require().IsType(&ocpp.Error{}, result) ocppErr = result.(*ocpp.Error) - assert.Equal(t, tc.expectedErr.Code, ocppErr.Code) - assert.Equal(t, tc.expectedErr.Description, ocppErr.Description) + suite.Equal(tc.expectedErr.Code, ocppErr.Code) + suite.Equal(tc.expectedErr.Description, ocppErr.Description) }) } } func (suite *OcppV16TestSuite) TestCentralSystemSendResponseError() { - t := suite.T() wsId := "test_id" channel := NewMockWebSocket(wsId) var ocppErr *ocpp.Error @@ -108,52 +105,52 @@ func (suite *OcppV16TestSuite) TestCentralSystemSendResponseError() { rawMsg := args.Get(0) bytes := rawMsg.([]byte) err := suite.mockWsServer.MessageHandler(channel, bytes) - assert.Nil(t, err) + suite.Nil(err) }) suite.mockWsServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) suite.mockWsServer.On("Write", mock.AnythingOfType("string"), mock.Anything).Return(nil).Run(func(args mock.Arguments) { rawMsg := args.Get(1) bytes := rawMsg.([]byte) err := suite.mockWsClient.MessageHandler(bytes) - assert.NoError(t, err) + suite.NoError(err) }) // Run Tests suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start("someUrl") - require.Nil(t, err) + suite.Require().Nil(err) // Test 1: occurrence validation error dataTransferConfirmation := core.NewDataTransferConfirmation(core.DataTransferStatusAccepted) dataTransferConfirmation.Data = CustomData{Field1: "", Field2: 42} coreListener.On("OnDataTransfer", mock.AnythingOfType("string"), mock.Anything).Return(dataTransferConfirmation, nil) response, err = suite.chargePoint.DataTransfer("vendor1") - require.Nil(t, response) - require.Error(t, err) - require.IsType(t, &ocpp.Error{}, err) + suite.Require().Nil(response) + suite.Require().Error(err) + suite.Require().IsType(&ocpp.Error{}, err) ocppErr = err.(*ocpp.Error) - assert.Equal(t, ocppj.OccurrenceConstraintViolationV16, ocppErr.Code) - assert.Equal(t, "Field CallResult.Payload.Data.Field1 required but not found for feature DataTransfer", ocppErr.Description) + suite.Equal(ocppj.OccurrenceConstraintViolationV16, ocppErr.Code) + suite.Equal("Field CallResult.Payload.Data.Field1 required but not found for feature DataTransfer", ocppErr.Description) // Test 2: marshaling error dataTransferConfirmation = core.NewDataTransferConfirmation(core.DataTransferStatusAccepted) dataTransferConfirmation.Data = make(chan struct{}) coreListener.ExpectedCalls = nil coreListener.On("OnDataTransfer", mock.AnythingOfType("string"), mock.Anything).Return(dataTransferConfirmation, nil) response, err = suite.chargePoint.DataTransfer("vendor1") - require.Nil(t, response) - require.Error(t, err) - require.IsType(t, &ocpp.Error{}, err) + suite.Require().Nil(response) + suite.Require().Error(err) + suite.Require().IsType(&ocpp.Error{}, err) ocppErr = err.(*ocpp.Error) - assert.Equal(t, ocppj.GenericError, ocppErr.Code) - assert.Equal(t, "json: unsupported type: chan struct {}", ocppErr.Description) + suite.Equal(ocppj.GenericError, ocppErr.Code) + suite.Equal("json: unsupported type: chan struct {}", ocppErr.Description) // Test 3: no results in callback coreListener.ExpectedCalls = nil coreListener.On("OnDataTransfer", mock.AnythingOfType("string"), mock.Anything).Return(nil, nil) response, err = suite.chargePoint.DataTransfer("vendor1") - require.Nil(t, response) - require.Error(t, err) - require.IsType(t, &ocpp.Error{}, err) + suite.Require().Nil(response) + suite.Require().Error(err) + suite.Require().IsType(&ocpp.Error{}, err) ocppErr = err.(*ocpp.Error) - assert.Equal(t, ocppj.GenericError, ocppErr.Code) - assert.Equal(t, fmt.Sprintf("empty confirmation to %s for request 1234", wsId), ocppErr.Description) + suite.Equal(ocppj.GenericError, ocppErr.Code) + suite.Equal(fmt.Sprintf("empty confirmation to %s for request 1234", wsId), ocppErr.Description) } func (suite *OcppV16TestSuite) TestErrorCodes() { diff --git a/ocpp1.6_test/remote_start_transaction_test.go b/ocpp1.6_test/remote_start_transaction_test.go index 32e31425..fde0a396 100644 --- a/ocpp1.6_test/remote_start_transaction_test.go +++ b/ocpp1.6_test/remote_start_transaction_test.go @@ -3,16 +3,13 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Test func (suite *OcppV16TestSuite) TestRemoteStartTransactionRequestValidation() { - t := suite.T() chargingSchedule := types.NewChargingSchedule(types.ChargingRateUnitWatts, types.NewChargingSchedulePeriod(0, 10.0)) chargingProfile := types.NewChargingProfile(1, 1, types.ChargingProfilePurposeChargePointMaxProfile, types.ChargingProfileKindAbsolute, chargingSchedule) var requestTable = []GenericTestEntry{ @@ -23,22 +20,20 @@ func (suite *OcppV16TestSuite) TestRemoteStartTransactionRequestValidation() { {core.RemoteStartTransactionRequest{}, false}, {core.RemoteStartTransactionRequest{IdTag: ">20..................", ConnectorId: newInt(1)}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestRemoteStartTransactionConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {core.RemoteStartTransactionConfirmation{Status: types.RemoteStartStopStatusAccepted}, true}, {core.RemoteStartTransactionConfirmation{Status: types.RemoteStartStopStatusRejected}, true}, {core.RemoteStartTransactionConfirmation{Status: "invalidRemoteStartTransactionStatus"}, false}, {core.RemoteStartTransactionConfirmation{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestRemoteStartTransactionE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -73,44 +68,44 @@ func (suite *OcppV16TestSuite) TestRemoteStartTransactionE2EMocked() { coreListener := &MockChargePointCoreListener{} coreListener.On("OnRemoteStartTransaction", mock.Anything).Return(RemoteStartTransactionConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*core.RemoteStartTransactionRequest) - require.NotNil(t, request) - require.True(t, ok) - assert.Equal(t, *connectorId, *request.ConnectorId) - assert.Equal(t, idTag, request.IdTag) - require.NotNil(t, request.ChargingProfile) - assert.Equal(t, chargingProfileId, request.ChargingProfile.ChargingProfileId) - assert.Equal(t, stackLevel, request.ChargingProfile.StackLevel) - assert.Equal(t, chargingProfilePurpose, request.ChargingProfile.ChargingProfilePurpose) - assert.Equal(t, chargingProfileKind, request.ChargingProfile.ChargingProfileKind) - assert.Equal(t, types.RecurrencyKindType(""), request.ChargingProfile.RecurrencyKind) - assert.Nil(t, request.ChargingProfile.ValidFrom) - assert.Nil(t, request.ChargingProfile.ValidTo) - require.NotNil(t, request.ChargingProfile.ChargingSchedule) - assert.Equal(t, chargingRateUnit, request.ChargingProfile.ChargingSchedule.ChargingRateUnit) - require.Len(t, request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod, 1) - assert.Equal(t, startPeriod, request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod[0].StartPeriod) - assert.Equal(t, limit, request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod[0].Limit) - assert.Nil(t, request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod[0].NumberPhases) + suite.Require().NotNil(request) + suite.Require().True(ok) + suite.Equal(*connectorId, *request.ConnectorId) + suite.Equal(idTag, request.IdTag) + suite.Require().NotNil(request.ChargingProfile) + suite.Equal(chargingProfileId, request.ChargingProfile.ChargingProfileId) + suite.Equal(stackLevel, request.ChargingProfile.StackLevel) + suite.Equal(chargingProfilePurpose, request.ChargingProfile.ChargingProfilePurpose) + suite.Equal(chargingProfileKind, request.ChargingProfile.ChargingProfileKind) + suite.Equal(types.RecurrencyKindType(""), request.ChargingProfile.RecurrencyKind) + suite.Nil(request.ChargingProfile.ValidFrom) + suite.Nil(request.ChargingProfile.ValidTo) + suite.Require().NotNil(request.ChargingProfile.ChargingSchedule) + suite.Equal(chargingRateUnit, request.ChargingProfile.ChargingSchedule.ChargingRateUnit) + suite.Require().Len(request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod, 1) + suite.Equal(startPeriod, request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod[0].StartPeriod) + suite.Equal(limit, request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod[0].Limit) + suite.Nil(request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod[0].NumberPhases) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, coreListener, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - assert.Nil(t, err) + suite.Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.RemoteStartTransaction(wsId, func(confirmation *core.RemoteStartTransactionConfirmation, err error) { - assert.Nil(t, err) - assert.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Nil(err) + suite.NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, idTag, func(request *core.RemoteStartTransactionRequest) { request.ConnectorId = connectorId request.ChargingProfile = chargingProfile }) - assert.Nil(t, err) + suite.Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestRemoteStartTransactionInvalidEndpoint() { diff --git a/ocpp1.6_test/remote_stop_transaction_test.go b/ocpp1.6_test/remote_stop_transaction_test.go index 7f9ec40c..8c9642ab 100644 --- a/ocpp1.6_test/remote_stop_transaction_test.go +++ b/ocpp1.6_test/remote_stop_transaction_test.go @@ -3,37 +3,32 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Test func (suite *OcppV16TestSuite) TestRemoteStopTransactionRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {core.RemoteStopTransactionRequest{TransactionId: 1}, true}, {core.RemoteStopTransactionRequest{}, true}, {core.RemoteStopTransactionRequest{TransactionId: -1}, true}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestRemoteStopTransactionConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {core.RemoteStopTransactionConfirmation{Status: types.RemoteStartStopStatusAccepted}, true}, {core.RemoteStopTransactionConfirmation{Status: types.RemoteStartStopStatusRejected}, true}, {core.RemoteStopTransactionConfirmation{Status: "invalidRemoteStopTransactionStatus"}, false}, {core.RemoteStopTransactionConfirmation{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestRemoteStopTransactionE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -47,26 +42,26 @@ func (suite *OcppV16TestSuite) TestRemoteStopTransactionE2EMocked() { coreListener := &MockChargePointCoreListener{} coreListener.On("OnRemoteStopTransaction", mock.Anything).Return(RemoteStopTransactionConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*core.RemoteStopTransactionRequest) - require.NotNil(t, request) - require.True(t, ok) - assert.Equal(t, transactionId, request.TransactionId) + suite.Require().NotNil(request) + suite.Require().True(ok) + suite.Equal(transactionId, request.TransactionId) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, coreListener, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.RemoteStopTransaction(wsId, func(confirmation *core.RemoteStopTransactionConfirmation, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, transactionId) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestRemoteStopTransactionInvalidEndpoint() { diff --git a/ocpp1.6_test/reserve_now_test.go b/ocpp1.6_test/reserve_now_test.go index 7b87d2ca..f4a55dda 100644 --- a/ocpp1.6_test/reserve_now_test.go +++ b/ocpp1.6_test/reserve_now_test.go @@ -4,16 +4,13 @@ import ( "fmt" "time" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Test func (suite *OcppV16TestSuite) TestReserveNowRequestValidation() { - t := suite.T() requestTable := []GenericTestEntry{ {reservation.ReserveNowRequest{ConnectorId: 1, ExpiryDate: types.NewDateTime(time.Now()), IdTag: "12345", ReservationId: 42, ParentIdTag: "9999"}, true}, {reservation.ReserveNowRequest{ConnectorId: 1, ExpiryDate: types.NewDateTime(time.Now()), IdTag: "12345", ReservationId: 42}, true}, @@ -26,21 +23,19 @@ func (suite *OcppV16TestSuite) TestReserveNowRequestValidation() { {reservation.ReserveNowRequest{ConnectorId: 1, ExpiryDate: types.NewDateTime(time.Now()), IdTag: ">20.................."}, false}, {reservation.ReserveNowRequest{ConnectorId: 1, ExpiryDate: types.NewDateTime(time.Now()), IdTag: "12345", ReservationId: 42, ParentIdTag: ">20.................."}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestReserveNowConfirmationValidation() { - t := suite.T() confirmationTable := []GenericTestEntry{ {reservation.ReserveNowConfirmation{Status: reservation.ReservationStatusAccepted}, true}, {reservation.ReserveNowConfirmation{Status: "invalidReserveNowStatus"}, false}, {reservation.ReserveNowConfirmation{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestReserveNowE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -59,14 +54,14 @@ func (suite *OcppV16TestSuite) TestReserveNowE2EMocked() { reservationListener := &MockChargePointReservationListener{} reservationListener.On("OnReserveNow", mock.Anything).Return(ReserveNowConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*reservation.ReserveNowRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, connectorId, request.ConnectorId) - require.NotNil(t, request.ExpiryDate) - assertDateTimeEquality(t, *expiryDate, *request.ExpiryDate) - assert.Equal(t, idTag, request.IdTag) - assert.Equal(t, parentIdTag, request.ParentIdTag) - assert.Equal(t, reservationId, request.ReservationId) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(connectorId, request.ConnectorId) + suite.Require().NotNil(request.ExpiryDate) + assertDateTimeEquality(suite, *expiryDate, *request.ExpiryDate) + suite.Equal(idTag, request.IdTag) + suite.Equal(parentIdTag, request.ParentIdTag) + suite.Equal(reservationId, request.ReservationId) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, nil, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) @@ -74,19 +69,19 @@ func (suite *OcppV16TestSuite) TestReserveNowE2EMocked() { // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.ReserveNow(wsId, func(confirmation *reservation.ReserveNowConfirmation, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, connectorId, expiryDate, idTag, reservationId, func(request *reservation.ReserveNowRequest) { request.ParentIdTag = parentIdTag }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestReserveNowInvalidEndpoint() { diff --git a/ocpp1.6_test/reset_test.go b/ocpp1.6_test/reset_test.go index eaea7ed4..0102878d 100644 --- a/ocpp1.6_test/reset_test.go +++ b/ocpp1.6_test/reset_test.go @@ -3,37 +3,32 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" ) func (suite *OcppV16TestSuite) TestResetRequestValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {core.ResetRequest{Type: core.ResetTypeHard}, true}, {core.ResetRequest{Type: core.ResetTypeSoft}, true}, {core.ResetRequest{Type: "invalidResetType"}, false}, {core.ResetRequest{}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV16TestSuite) TestResetConfirmationValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {core.ResetConfirmation{Status: core.ResetStatusAccepted}, true}, {core.ResetConfirmation{Status: core.ResetStatusRejected}, true}, {core.ResetConfirmation{Status: "invalidResetStatus"}, false}, {core.ResetConfirmation{}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } // Test func (suite *OcppV16TestSuite) TestResetE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -47,26 +42,26 @@ func (suite *OcppV16TestSuite) TestResetE2EMocked() { coreListener := &MockChargePointCoreListener{} coreListener.On("OnReset", mock.Anything).Return(resetConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*core.ResetRequest) - require.NotNil(t, request) - require.True(t, ok) - assert.Equal(t, resetType, request.Type) + suite.Require().NotNil(request) + suite.Require().True(ok) + suite.Equal(resetType, request.Type) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, coreListener, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.Reset(wsId, func(confirmation *core.ResetConfirmation, err error) { - require.NotNil(t, confirmation) - require.Nil(t, err) - assert.Equal(t, status, confirmation.Status) + suite.Require().NotNil(confirmation) + suite.Require().Nil(err) + suite.Equal(status, confirmation.Status) resultChannel <- true }, resetType) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestResetInvalidEndpoint() { diff --git a/ocpp1.6_test/send_local_list_test.go b/ocpp1.6_test/send_local_list_test.go index 245a0beb..5186a246 100644 --- a/ocpp1.6_test/send_local_list_test.go +++ b/ocpp1.6_test/send_local_list_test.go @@ -4,16 +4,13 @@ import ( "fmt" "time" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Test func (suite *OcppV16TestSuite) TestSendLocalListRequestValidation() { - t := suite.T() localAuthEntry := localauth.AuthorizationData{IdTag: "12345", IdTagInfo: &types.IdTagInfo{ ExpiryDate: types.NewDateTime(time.Now().Add(time.Hour * 8)), ParentIdTag: "000000", @@ -36,21 +33,19 @@ func (suite *OcppV16TestSuite) TestSendLocalListRequestValidation() { {localauth.SendLocalListRequest{ListVersion: 1}, false}, {localauth.SendLocalListRequest{}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestSendLocalListConfirmationValidation() { - t := suite.T() confirmationTable := []GenericTestEntry{ {localauth.SendLocalListConfirmation{Status: localauth.UpdateStatusAccepted}, true}, {localauth.SendLocalListConfirmation{Status: "invalidStatus"}, false}, {localauth.SendLocalListConfirmation{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestSendLocalListE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -71,16 +66,16 @@ func (suite *OcppV16TestSuite) TestSendLocalListE2EMocked() { localAuthListListener := &MockChargePointLocalAuthListListener{} localAuthListListener.On("OnSendLocalList", mock.Anything).Return(sendLocalListConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*localauth.SendLocalListRequest) - require.NotNil(t, request) - require.True(t, ok) - assert.Equal(t, listVersion, request.ListVersion) - assert.Equal(t, updateType, request.UpdateType) - require.Len(t, request.LocalAuthorizationList, 1) - assert.Equal(t, localAuthEntry.IdTag, request.LocalAuthorizationList[0].IdTag) - require.NotNil(t, request.LocalAuthorizationList[0].IdTagInfo) - assert.Equal(t, localAuthEntry.IdTagInfo.Status, request.LocalAuthorizationList[0].IdTagInfo.Status) - assert.Equal(t, localAuthEntry.IdTagInfo.ParentIdTag, request.LocalAuthorizationList[0].IdTagInfo.ParentIdTag) - assertDateTimeEquality(t, *localAuthEntry.IdTagInfo.ExpiryDate, *request.LocalAuthorizationList[0].IdTagInfo.ExpiryDate) + suite.Require().NotNil(request) + suite.Require().True(ok) + suite.Equal(listVersion, request.ListVersion) + suite.Equal(updateType, request.UpdateType) + suite.Require().Len(request.LocalAuthorizationList, 1) + suite.Equal(localAuthEntry.IdTag, request.LocalAuthorizationList[0].IdTag) + suite.Require().NotNil(request.LocalAuthorizationList[0].IdTagInfo) + suite.Equal(localAuthEntry.IdTagInfo.Status, request.LocalAuthorizationList[0].IdTagInfo.Status) + suite.Equal(localAuthEntry.IdTagInfo.ParentIdTag, request.LocalAuthorizationList[0].IdTagInfo.ParentIdTag) + assertDateTimeEquality(suite, *localAuthEntry.IdTagInfo.ExpiryDate, *request.LocalAuthorizationList[0].IdTagInfo.ExpiryDate) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) suite.chargePoint.SetLocalAuthListHandler(localAuthListListener) @@ -88,19 +83,19 @@ func (suite *OcppV16TestSuite) TestSendLocalListE2EMocked() { // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.SendLocalList(wsId, func(confirmation *localauth.SendLocalListConfirmation, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, listVersion, updateType, func(request *localauth.SendLocalListRequest) { request.LocalAuthorizationList = []localauth.AuthorizationData{localAuthEntry} }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestSendLocalListInvalidEndpoint() { diff --git a/ocpp1.6_test/set_charging_profile_test.go b/ocpp1.6_test/set_charging_profile_test.go index 0758d1fb..80db92e0 100644 --- a/ocpp1.6_test/set_charging_profile_test.go +++ b/ocpp1.6_test/set_charging_profile_test.go @@ -3,16 +3,13 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Test func (suite *OcppV16TestSuite) TestSetChargingProfileRequestValidation() { - t := suite.T() chargingSchedule := types.NewChargingSchedule(types.ChargingRateUnitWatts, types.NewChargingSchedulePeriod(0, 10.0)) chargingProfile := types.NewChargingProfile(1, 1, types.ChargingProfilePurposeChargePointMaxProfile, types.ChargingProfileKindAbsolute, chargingSchedule) requestTable := []GenericTestEntry{ @@ -22,21 +19,19 @@ func (suite *OcppV16TestSuite) TestSetChargingProfileRequestValidation() { {smartcharging.SetChargingProfileRequest{ConnectorId: 1}, false}, {smartcharging.SetChargingProfileRequest{ConnectorId: -1, ChargingProfile: chargingProfile}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestSetChargingProfileConfirmationValidation() { - t := suite.T() confirmationTable := []GenericTestEntry{ {smartcharging.SetChargingProfileConfirmation{Status: smartcharging.ChargingProfileStatusAccepted}, true}, {smartcharging.SetChargingProfileConfirmation{Status: "invalidChargingProfileStatus"}, false}, {smartcharging.SetChargingProfileConfirmation{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestSetChargingProfileE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -69,25 +64,25 @@ func (suite *OcppV16TestSuite) TestSetChargingProfileE2EMocked() { smartChargingListener := &MockChargePointSmartChargingListener{} smartChargingListener.On("OnSetChargingProfile", mock.Anything).Return(SetChargingProfileConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*smartcharging.SetChargingProfileRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, connectorId, request.ConnectorId) - assert.Equal(t, chargingProfileId, request.ChargingProfile.ChargingProfileId) - assert.Equal(t, chargingProfileKind, request.ChargingProfile.ChargingProfileKind) - assert.Equal(t, chargingProfilePurpose, request.ChargingProfile.ChargingProfilePurpose) - assert.Equal(t, types.RecurrencyKindType(""), request.ChargingProfile.RecurrencyKind) - assert.Equal(t, stackLevel, request.ChargingProfile.StackLevel) - assert.Equal(t, 0, request.ChargingProfile.TransactionId) - assert.Nil(t, request.ChargingProfile.ValidFrom) - assert.Nil(t, request.ChargingProfile.ValidTo) - assert.Equal(t, chargingRateUnit, request.ChargingProfile.ChargingSchedule.ChargingRateUnit) - assert.Nil(t, request.ChargingProfile.ChargingSchedule.MinChargingRate) - assert.Nil(t, request.ChargingProfile.ChargingSchedule.Duration) - assert.Nil(t, request.ChargingProfile.ChargingSchedule.StartSchedule) - require.Len(t, request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod, 1) - assert.Equal(t, limit, request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod[0].Limit) - assert.Equal(t, startPeriod, request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod[0].StartPeriod) - assert.Nil(t, request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod[0].NumberPhases) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(connectorId, request.ConnectorId) + suite.Equal(chargingProfileId, request.ChargingProfile.ChargingProfileId) + suite.Equal(chargingProfileKind, request.ChargingProfile.ChargingProfileKind) + suite.Equal(chargingProfilePurpose, request.ChargingProfile.ChargingProfilePurpose) + suite.Equal(types.RecurrencyKindType(""), request.ChargingProfile.RecurrencyKind) + suite.Equal(stackLevel, request.ChargingProfile.StackLevel) + suite.Equal(0, request.ChargingProfile.TransactionId) + suite.Nil(request.ChargingProfile.ValidFrom) + suite.Nil(request.ChargingProfile.ValidTo) + suite.Equal(chargingRateUnit, request.ChargingProfile.ChargingSchedule.ChargingRateUnit) + suite.Nil(request.ChargingProfile.ChargingSchedule.MinChargingRate) + suite.Nil(request.ChargingProfile.ChargingSchedule.Duration) + suite.Nil(request.ChargingProfile.ChargingSchedule.StartSchedule) + suite.Require().Len(request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod, 1) + suite.Equal(limit, request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod[0].Limit) + suite.Equal(startPeriod, request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod[0].StartPeriod) + suite.Nil(request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod[0].NumberPhases) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, nil, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) @@ -95,17 +90,17 @@ func (suite *OcppV16TestSuite) TestSetChargingProfileE2EMocked() { // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.SetChargingProfile(wsId, func(confirmation *smartcharging.SetChargingProfileConfirmation, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, connectorId, chargingProfile) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestSetChargingProfileInvalidEndpoint() { diff --git a/ocpp1.6_test/sign_certificate_test.go b/ocpp1.6_test/sign_certificate_test.go index 17dbd375..31c1ad0e 100644 --- a/ocpp1.6_test/sign_certificate_test.go +++ b/ocpp1.6_test/sign_certificate_test.go @@ -3,12 +3,10 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/security" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/lorenzodonini/ocpp-go/ocpp1.6_test/mocks" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/security" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6_test/mocks" ) // Test @@ -19,18 +17,17 @@ func (suite *OcppV16TestSuite) TestSignCertificateRequestValidation() { {security.SignCertificateRequest{}, false}, {security.SignCertificateRequest{CSR: "deadc0de", CertificateType: "invalidType"}, false}, } - ExecuteGenericTestTable(suite.T(), requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestSignCertificateConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {security.SignCertificateResponse{Status: types.GenericStatusAccepted}, true}, {security.SignCertificateResponse{Status: types.GenericStatusAccepted}, true}, {security.SignCertificateResponse{}, false}, {security.SignCertificateResponse{Status: "invalidStatus"}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestSignCertificateE2EMocked() { @@ -49,8 +46,8 @@ func (suite *OcppV16TestSuite) TestSignCertificateE2EMocked() { handler := mocks.NewMockSecurityCentralSystemHandler(t) handler.EXPECT().OnSignCertificate(wsId, mock.Anything).RunAndReturn(func(s string, request *security.SignCertificateRequest) (*security.SignCertificateResponse, error) { - assert.Equal(t, csr, request.CSR) - assert.Equal(t, certificateType, request.CertificateType) + suite.Equal(csr, request.CSR) + suite.Equal(certificateType, request.CertificateType) return signCertificateResponse, nil }) @@ -61,13 +58,13 @@ func (suite *OcppV16TestSuite) TestSignCertificateE2EMocked() { // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) response, err := suite.chargePoint.SignCertificate(csr, func(request *security.SignCertificateRequest) { request.CertificateType = certificateType }) - require.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, status, response.Status) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Equal(status, response.Status) } func (suite *OcppV16TestSuite) TestSignCertificateInvalidEndpoint() { diff --git a/ocpp1.6_test/signed_update_firmware_test.go b/ocpp1.6_test/signed_update_firmware_test.go index 561219ad..cf1fd830 100644 --- a/ocpp1.6_test/signed_update_firmware_test.go +++ b/ocpp1.6_test/signed_update_firmware_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/securefirmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/lorenzodonini/ocpp-go/ocpp1.6_test/mocks" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/securefirmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6_test/mocks" ) // Test func (suite *OcppV16TestSuite) TestSignedUpdateFirmwareRequestValidation() { - t := suite.T() fw := securefirmware.Firmware{ Location: "https://someurl", RetrieveDateTime: types.NewDateTime(time.Now()), @@ -36,11 +33,10 @@ func (suite *OcppV16TestSuite) TestSignedUpdateFirmwareRequestValidation() { {securefirmware.SignedUpdateFirmwareRequest{Retries: newInt(5), RetryInterval: newInt(300), RequestID: 42, Firmware: securefirmware.Firmware{Location: "https://someurl", InstallDateTime: types.NewDateTime(time.Now()), SigningCertificate: "1337c0de", Signature: "deadc0de"}}, false}, {securefirmware.SignedUpdateFirmwareRequest{Retries: newInt(5), RetryInterval: newInt(300), RequestID: 42, Firmware: securefirmware.Firmware{Location: ">512.............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", RetrieveDateTime: types.NewDateTime(time.Now()), InstallDateTime: types.NewDateTime(time.Now()), SigningCertificate: "1337c0de", Signature: "deadc0de"}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestSignedUpdateFirmwareResponseValidation() { - t := suite.T() var responseTable = []GenericTestEntry{ {securefirmware.SignedUpdateFirmwareResponse{Status: securefirmware.UpdateFirmwareStatusAccepted}, true}, {securefirmware.SignedUpdateFirmwareResponse{Status: securefirmware.UpdateFirmwareStatusAccepted}, true}, @@ -48,7 +44,7 @@ func (suite *OcppV16TestSuite) TestSignedUpdateFirmwareResponseValidation() { {securefirmware.SignedUpdateFirmwareResponse{}, false}, {securefirmware.SignedUpdateFirmwareResponse{Status: "invalidFirmwareUpdateStatus"}, false}, } - ExecuteGenericTestTable(t, responseTable) + ExecuteGenericTestTable(suite, responseTable) } func (suite *OcppV16TestSuite) TestSignedUpdateFirmwareE2EMocked() { @@ -75,14 +71,14 @@ func (suite *OcppV16TestSuite) TestSignedUpdateFirmwareE2EMocked() { handler := mocks.NewMockSecureFirmwareChargePointHandler(t) handler.EXPECT().OnSignedUpdateFirmware(mock.Anything).RunAndReturn(func(request *securefirmware.SignedUpdateFirmwareRequest) (*securefirmware.SignedUpdateFirmwareResponse, error) { - assert.Equal(t, *retries, *request.Retries) - assert.Equal(t, *retryInterval, *request.RetryInterval) - assert.Equal(t, requestID, request.RequestID) - assert.Equal(t, fw.Location, request.Firmware.Location) - assertDateTimeEquality(t, *fw.RetrieveDateTime, *request.Firmware.RetrieveDateTime) - assertDateTimeEquality(t, *fw.InstallDateTime, *request.Firmware.InstallDateTime) - assert.Equal(t, fw.SigningCertificate, request.Firmware.SigningCertificate) - assert.Equal(t, fw.Signature, request.Firmware.Signature) + suite.Equal(*retries, *request.Retries) + suite.Equal(*retryInterval, *request.RetryInterval) + suite.Equal(requestID, request.RequestID) + suite.Equal(fw.Location, request.Firmware.Location) + assertDateTimeEquality(suite, *fw.RetrieveDateTime, *request.Firmware.RetrieveDateTime) + assertDateTimeEquality(suite, *fw.InstallDateTime, *request.Firmware.InstallDateTime) + suite.Equal(fw.SigningCertificate, request.Firmware.SigningCertificate) + suite.Equal(fw.Signature, request.Firmware.Signature) return updateFirmwareResponse, nil }) @@ -94,20 +90,20 @@ func (suite *OcppV16TestSuite) TestSignedUpdateFirmwareE2EMocked() { // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - assert.Nil(t, err) + suite.Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.SignedUpdateFirmware(wsId, func(resp *securefirmware.SignedUpdateFirmwareResponse, err error) { - assert.Nil(t, err) - require.NotNil(t, resp) - assert.Equal(t, status, resp.Status) + suite.Nil(err) + suite.Require().NotNil(resp) + suite.Equal(status, resp.Status) resultChannel <- true }, requestID, fw, func(request *securefirmware.SignedUpdateFirmwareRequest) { request.Retries = retries request.RetryInterval = retryInterval }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestSignedUpdateFirmwareInvalidEndpoint() { diff --git a/ocpp1.6_test/start_transaction_test.go b/ocpp1.6_test/start_transaction_test.go index 5991acb5..10455e94 100644 --- a/ocpp1.6_test/start_transaction_test.go +++ b/ocpp1.6_test/start_transaction_test.go @@ -4,16 +4,13 @@ import ( "fmt" "time" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Test func (suite *OcppV16TestSuite) TestStartTransactionRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {core.StartTransactionRequest{ConnectorId: 1, IdTag: "12345", MeterStart: 100, ReservationId: newInt(42), Timestamp: types.NewDateTime(time.Now())}, true}, {core.StartTransactionRequest{ConnectorId: 1, IdTag: "12345", MeterStart: 100, Timestamp: types.NewDateTime(time.Now())}, true}, @@ -25,22 +22,20 @@ func (suite *OcppV16TestSuite) TestStartTransactionRequestValidation() { {core.StartTransactionRequest{ConnectorId: 1, MeterStart: 100, Timestamp: types.NewDateTime(time.Now())}, false}, {core.StartTransactionRequest{ConnectorId: 1, IdTag: "12345", MeterStart: 100}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestStartTransactionConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {core.StartTransactionConfirmation{IdTagInfo: &types.IdTagInfo{ExpiryDate: types.NewDateTime(time.Now().Add(time.Hour * 8)), ParentIdTag: "00000", Status: types.AuthorizationStatusAccepted}, TransactionId: 10}, true}, {core.StartTransactionConfirmation{IdTagInfo: &types.IdTagInfo{ExpiryDate: types.NewDateTime(time.Now().Add(time.Hour * 8)), ParentIdTag: "00000", Status: types.AuthorizationStatusAccepted}}, true}, {core.StartTransactionConfirmation{IdTagInfo: &types.IdTagInfo{Status: "invalidAuthorizationStatus"}, TransactionId: 10}, false}, {core.StartTransactionConfirmation{TransactionId: 10}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestStartTransactionE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -64,28 +59,28 @@ func (suite *OcppV16TestSuite) TestStartTransactionE2EMocked() { coreListener := &MockCentralSystemCoreListener{} coreListener.On("OnStartTransaction", mock.AnythingOfType("string"), mock.Anything).Return(startTransactionConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*core.StartTransactionRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, connectorId, request.ConnectorId) - assert.Equal(t, idTag, request.IdTag) - assert.Equal(t, meterStart, request.MeterStart) - assert.Equal(t, *reservationId, *request.ReservationId) - assertDateTimeEquality(t, *timestamp, *request.Timestamp) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(connectorId, request.ConnectorId) + suite.Equal(idTag, request.IdTag) + suite.Equal(meterStart, request.MeterStart) + suite.Equal(*reservationId, *request.ReservationId) + assertDateTimeEquality(suite, *timestamp, *request.Timestamp) }) setupDefaultCentralSystemHandlers(suite, coreListener, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: responseRaw, forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, nil, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: requestRaw, forwardWrittenMessage: true}) // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) confirmation, err := suite.chargePoint.StartTransaction(connectorId, idTag, meterStart, timestamp, func(request *core.StartTransactionRequest) { request.ReservationId = reservationId }) - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.IdTagInfo.Status) - assert.Equal(t, parentIdTag, confirmation.IdTagInfo.ParentIdTag) - assertDateTimeEquality(t, *expiryDate, *confirmation.IdTagInfo.ExpiryDate) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.IdTagInfo.Status) + suite.Equal(parentIdTag, confirmation.IdTagInfo.ParentIdTag) + assertDateTimeEquality(suite, *expiryDate, *confirmation.IdTagInfo.ExpiryDate) } func (suite *OcppV16TestSuite) TestStartTransactionInvalidEndpoint() { diff --git a/ocpp1.6_test/status_notification_test.go b/ocpp1.6_test/status_notification_test.go index 376aa611..6c034792 100644 --- a/ocpp1.6_test/status_notification_test.go +++ b/ocpp1.6_test/status_notification_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Test func (suite *OcppV16TestSuite) TestStatusNotificationRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {core.StatusNotificationRequest{ConnectorId: 0, ErrorCode: core.NoError, Info: "mockInfo", Status: core.ChargePointStatusAvailable, Timestamp: types.NewDateTime(time.Now()), VendorId: "mockId", VendorErrorCode: "mockErrorCode"}, true}, {core.StatusNotificationRequest{ConnectorId: 0, ErrorCode: core.NoError, Status: core.ChargePointStatusAvailable}, true}, @@ -29,19 +26,17 @@ func (suite *OcppV16TestSuite) TestStatusNotificationRequestValidation() { {core.StatusNotificationRequest{ConnectorId: 0, ErrorCode: core.NoError, VendorId: ">255............................................................................................................................................................................................................................................................", Status: core.ChargePointStatusAvailable}, false}, //{ocpp16.StatusNotificationRequest{ConnectorId: 0, ErrorCode: ocpp16.NoError, Info: "mockInfo", Status: ocpp16.ChargePointStatusAvailable, Timestamp: ocpp16.DateTime{Time: time.Now().Add(1 * time.Hour)}, VendorId: "mockId", VendorErrorCode: "mockErrorCode"}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestStatusNotificationConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {core.StatusNotificationConfirmation{}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestStatusNotificationE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -60,30 +55,30 @@ func (suite *OcppV16TestSuite) TestStatusNotificationE2EMocked() { coreListener := &MockCentralSystemCoreListener{} coreListener.On("OnStatusNotification", mock.AnythingOfType("string"), mock.Anything).Return(statusNotificationConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*core.StatusNotificationRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, connectorId, request.ConnectorId) - assert.Equal(t, cpErrorCode, request.ErrorCode) - assert.Equal(t, status, request.Status) - assert.Equal(t, info, request.Info) - assert.Equal(t, vendorId, request.VendorId) - assert.Equal(t, vendorErrorCode, request.VendorErrorCode) - assertDateTimeEquality(t, *timestamp, *request.Timestamp) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(connectorId, request.ConnectorId) + suite.Equal(cpErrorCode, request.ErrorCode) + suite.Equal(status, request.Status) + suite.Equal(info, request.Info) + suite.Equal(vendorId, request.VendorId) + suite.Equal(vendorErrorCode, request.VendorErrorCode) + assertDateTimeEquality(suite, *timestamp, *request.Timestamp) }) setupDefaultCentralSystemHandlers(suite, coreListener, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, nil, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) confirmation, err := suite.chargePoint.StatusNotification(connectorId, cpErrorCode, status, func(request *core.StatusNotificationRequest) { request.Timestamp = timestamp request.Info = info request.VendorId = vendorId request.VendorErrorCode = vendorErrorCode }) - require.Nil(t, err) - require.NotNil(t, confirmation) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) } func (suite *OcppV16TestSuite) TestStatusNotificationInvalidEndpoint() { diff --git a/ocpp1.6_test/stop_transaction_test.go b/ocpp1.6_test/stop_transaction_test.go index c176875b..02f73d6a 100644 --- a/ocpp1.6_test/stop_transaction_test.go +++ b/ocpp1.6_test/stop_transaction_test.go @@ -4,16 +4,13 @@ import ( "fmt" "time" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Test func (suite *OcppV16TestSuite) TestStopTransactionRequestValidation() { - t := suite.T() transactionData := []types.MeterValue{{Timestamp: types.NewDateTime(time.Now()), SampledValue: []types.SampledValue{{Value: "value"}}}} var requestTable = []GenericTestEntry{ {core.StopTransactionRequest{IdTag: "12345", MeterStop: 100, Timestamp: types.NewDateTime(time.Now()), TransactionId: 1, Reason: core.ReasonEVDisconnected, TransactionData: transactionData}, true}, @@ -28,21 +25,19 @@ func (suite *OcppV16TestSuite) TestStopTransactionRequestValidation() { {core.StopTransactionRequest{IdTag: ">20..................", MeterStop: 100, Timestamp: types.NewDateTime(time.Now()), TransactionId: 1}, false}, {core.StopTransactionRequest{MeterStop: 100, Timestamp: types.NewDateTime(time.Now()), TransactionId: 1, TransactionData: []types.MeterValue{{Timestamp: types.NewDateTime(time.Now()), SampledValue: []types.SampledValue{}}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestStopTransactionConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {core.StopTransactionConfirmation{IdTagInfo: &types.IdTagInfo{ExpiryDate: types.NewDateTime(time.Now().Add(time.Hour * 8)), ParentIdTag: "00000", Status: types.AuthorizationStatusAccepted}}, true}, {core.StopTransactionConfirmation{}, true}, {core.StopTransactionConfirmation{IdTagInfo: &types.IdTagInfo{Status: "invalidAuthorizationStatus"}}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestStopTransactionE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -67,34 +62,34 @@ func (suite *OcppV16TestSuite) TestStopTransactionE2EMocked() { coreListener := &MockCentralSystemCoreListener{} coreListener.On("OnStopTransaction", mock.AnythingOfType("string"), mock.Anything).Return(stopTransactionConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*core.StopTransactionRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, meterStop, request.MeterStop) - assert.Equal(t, transactionId, request.TransactionId) - assert.Equal(t, idTag, request.IdTag) - assertDateTimeEquality(t, *timestamp, *request.Timestamp) - require.Len(t, request.TransactionData, 1) - assertDateTimeEquality(t, *timestamp, *request.TransactionData[0].Timestamp) - require.Len(t, request.TransactionData[0].SampledValue, 1) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(meterStop, request.MeterStop) + suite.Equal(transactionId, request.TransactionId) + suite.Equal(idTag, request.IdTag) + assertDateTimeEquality(suite, *timestamp, *request.Timestamp) + suite.Require().Len(request.TransactionData, 1) + assertDateTimeEquality(suite, *timestamp, *request.TransactionData[0].Timestamp) + suite.Require().Len(request.TransactionData[0].SampledValue, 1) sv := request.TransactionData[0].SampledValue[0] - assert.Equal(t, mockValue, sv.Value) - assert.Equal(t, mockUnit, sv.Unit) + suite.Equal(mockValue, sv.Value) + suite.Equal(mockUnit, sv.Unit) }) setupDefaultCentralSystemHandlers(suite, coreListener, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: responseRaw, forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, nil, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: requestRaw, forwardWrittenMessage: true}) // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) confirmation, err := suite.chargePoint.StopTransaction(meterStop, timestamp, transactionId, func(request *core.StopTransactionRequest) { request.IdTag = idTag request.TransactionData = meterValues }) - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.IdTagInfo.Status) - assert.Equal(t, parentIdTag, confirmation.IdTagInfo.ParentIdTag) - assertDateTimeEquality(t, *expiryDate, *confirmation.IdTagInfo.ExpiryDate) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.IdTagInfo.Status) + suite.Equal(parentIdTag, confirmation.IdTagInfo.ParentIdTag) + assertDateTimeEquality(suite, *expiryDate, *confirmation.IdTagInfo.ExpiryDate) } func (suite *OcppV16TestSuite) TestStopTransactionInvalidEndpoint() { diff --git a/ocpp1.6_test/trigger_message_test.go b/ocpp1.6_test/trigger_message_test.go index c85c2798..3eb5bbca 100644 --- a/ocpp1.6_test/trigger_message_test.go +++ b/ocpp1.6_test/trigger_message_test.go @@ -3,16 +3,13 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/remotetrigger" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/remotetrigger" ) // Test func (suite *OcppV16TestSuite) TestTriggerMessageRequestValidation() { - t := suite.T() requestTable := []GenericTestEntry{ {remotetrigger.TriggerMessageRequest{RequestedMessage: core.StatusNotificationFeatureName, ConnectorId: newInt(1)}, true}, {remotetrigger.TriggerMessageRequest{RequestedMessage: core.StatusNotificationFeatureName}, true}, @@ -21,21 +18,19 @@ func (suite *OcppV16TestSuite) TestTriggerMessageRequestValidation() { {remotetrigger.TriggerMessageRequest{RequestedMessage: core.StatusNotificationFeatureName, ConnectorId: newInt(-1)}, false}, {remotetrigger.TriggerMessageRequest{RequestedMessage: core.StartTransactionFeatureName}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestTriggerMessageConfirmationValidation() { - t := suite.T() confirmationTable := []GenericTestEntry{ {remotetrigger.TriggerMessageConfirmation{Status: remotetrigger.TriggerMessageStatusAccepted}, true}, {remotetrigger.TriggerMessageConfirmation{Status: "invalidTriggerMessageStatus"}, false}, {remotetrigger.TriggerMessageConfirmation{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestTriggerMessageE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -50,10 +45,10 @@ func (suite *OcppV16TestSuite) TestTriggerMessageE2EMocked() { remoteTriggerListener := &MockChargePointRemoteTriggerListener{} remoteTriggerListener.On("OnTriggerMessage", mock.Anything).Return(TriggerMessageConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*remotetrigger.TriggerMessageRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, requestedMessage, request.RequestedMessage) - assert.Equal(t, *connectorId, *request.ConnectorId) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(requestedMessage, request.RequestedMessage) + suite.Equal(*connectorId, *request.ConnectorId) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, nil, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) @@ -61,19 +56,19 @@ func (suite *OcppV16TestSuite) TestTriggerMessageE2EMocked() { // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.TriggerMessage(wsId, func(confirmation *remotetrigger.TriggerMessageConfirmation, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, requestedMessage, func(request *remotetrigger.TriggerMessageRequest) { request.ConnectorId = connectorId }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestTriggerMessageInvalidEndpoint() { diff --git a/ocpp1.6_test/unlock_connector_test.go b/ocpp1.6_test/unlock_connector_test.go index 1a6173cb..c115abec 100644 --- a/ocpp1.6_test/unlock_connector_test.go +++ b/ocpp1.6_test/unlock_connector_test.go @@ -3,35 +3,30 @@ package ocpp16_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/core" ) func (suite *OcppV16TestSuite) TestUnlockConnectorRequestValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {core.UnlockConnectorRequest{ConnectorId: 1}, true}, {core.UnlockConnectorRequest{ConnectorId: -1}, false}, {core.UnlockConnectorRequest{}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV16TestSuite) TestUnlockConnectorConfirmationValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {core.UnlockConnectorConfirmation{Status: core.UnlockStatusUnlocked}, true}, {core.UnlockConnectorConfirmation{Status: "invalidUnlockStatus"}, false}, {core.UnlockConnectorConfirmation{}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } // Test func (suite *OcppV16TestSuite) TestUnlockConnectorE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -45,26 +40,26 @@ func (suite *OcppV16TestSuite) TestUnlockConnectorE2EMocked() { coreListener := &MockChargePointCoreListener{} coreListener.On("OnUnlockConnector", mock.Anything).Return(unlockConnectorConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*core.UnlockConnectorRequest) - require.NotNil(t, request) - require.True(t, ok) - assert.Equal(t, connectorId, request.ConnectorId) + suite.Require().NotNil(request) + suite.Require().True(ok) + suite.Equal(connectorId, request.ConnectorId) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargePointHandlers(suite, coreListener, expectedChargePointOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}) // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.UnlockConnector(wsId, func(confirmation *core.UnlockConnectorConfirmation, err error) { - require.NotNil(t, confirmation) - require.Nil(t, err) - assert.Equal(t, status, confirmation.Status) + suite.Require().NotNil(confirmation) + suite.Require().Nil(err) + suite.Equal(status, confirmation.Status) resultChannel <- true }, connectorId) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestUnlockConnectorInvalidEndpoint() { diff --git a/ocpp1.6_test/update_firmware_test.go b/ocpp1.6_test/update_firmware_test.go index 19704b5f..f53e5e50 100644 --- a/ocpp1.6_test/update_firmware_test.go +++ b/ocpp1.6_test/update_firmware_test.go @@ -4,16 +4,13 @@ import ( "fmt" "time" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp1.6/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp1.6/types" ) // Test func (suite *OcppV16TestSuite) TestUpdateFirmwareRequestValidation() { - t := suite.T() requestTable := []GenericTestEntry{ {firmware.UpdateFirmwareRequest{Location: "ftp:some/path", Retries: newInt(10), RetryInterval: newInt(10), RetrieveDate: types.NewDateTime(time.Now())}, true}, {firmware.UpdateFirmwareRequest{Location: "ftp:some/path", Retries: newInt(10), RetrieveDate: types.NewDateTime(time.Now())}, true}, @@ -24,19 +21,17 @@ func (suite *OcppV16TestSuite) TestUpdateFirmwareRequestValidation() { {firmware.UpdateFirmwareRequest{Location: "ftp:some/path", Retries: newInt(-1), RetrieveDate: types.NewDateTime(time.Now())}, false}, {firmware.UpdateFirmwareRequest{Location: "ftp:some/path", RetryInterval: newInt(-1), RetrieveDate: types.NewDateTime(time.Now())}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV16TestSuite) TestUpdateFirmwareConfirmationValidation() { - t := suite.T() confirmationTable := []GenericTestEntry{ {firmware.UpdateFirmwareConfirmation{}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV16TestSuite) TestUpdateFirmwareE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -53,14 +48,14 @@ func (suite *OcppV16TestSuite) TestUpdateFirmwareE2EMocked() { firmwareListener := &MockChargePointFirmwareManagementListener{} firmwareListener.On("OnUpdateFirmware", mock.Anything).Return(updateFirmwareConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*firmware.UpdateFirmwareRequest) - require.NotNil(t, request) - require.True(t, ok) - assert.Equal(t, location, request.Location) - assert.NotNil(t, request.Retries) - assert.Equal(t, *retries, *request.Retries) - assert.NotNil(t, request.RetryInterval) - assert.Equal(t, *retryInterval, *request.RetryInterval) - assertDateTimeEquality(t, *retrieveDate, *request.RetrieveDate) + suite.Require().NotNil(request) + suite.Require().True(ok) + suite.Equal(location, request.Location) + suite.NotNil(request.Retries) + suite.Equal(*retries, *request.Retries) + suite.NotNil(request.RetryInterval) + suite.Equal(*retryInterval, *request.RetryInterval) + assertDateTimeEquality(suite, *retrieveDate, *request.RetrieveDate) }) setupDefaultCentralSystemHandlers(suite, nil, expectedCentralSystemOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) suite.chargePoint.SetFirmwareManagementHandler(firmwareListener) @@ -68,19 +63,19 @@ func (suite *OcppV16TestSuite) TestUpdateFirmwareE2EMocked() { // Run Test suite.centralSystem.Start(8887, "somePath") err := suite.chargePoint.Start(wsUrl) - assert.Nil(t, err) + suite.Nil(err) resultChannel := make(chan bool, 1) err = suite.centralSystem.UpdateFirmware(wsId, func(confirmation *firmware.UpdateFirmwareConfirmation, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) resultChannel <- true }, location, retrieveDate, func(request *firmware.UpdateFirmwareRequest) { request.RetryInterval = retryInterval request.Retries = retries }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV16TestSuite) TestUpdateFirmwareInvalidEndpoint() { diff --git a/ocpp2.0.1/authorization/authorization.go b/ocpp2.0.1/authorization/authorization.go index b21fe1e5..49223c8c 100644 --- a/ocpp2.0.1/authorization/authorization.go +++ b/ocpp2.0.1/authorization/authorization.go @@ -1,7 +1,7 @@ // The authorization functional block contains OCPP 2.0 authorization-related features. It contains different ways of authorizing a user, online and/or offline . package authorization -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Authorization profile. type CSMSHandler interface { diff --git a/ocpp2.0.1/authorization/authorize.go b/ocpp2.0.1/authorization/authorize.go index d04c97f3..61c3041a 100644 --- a/ocpp2.0.1/authorization/authorize.go +++ b/ocpp2.0.1/authorization/authorize.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Authorize (CS -> CSMS) -------------------- diff --git a/ocpp2.0.1/authorization/clear_cache.go b/ocpp2.0.1/authorization/clear_cache.go index 334d9d2f..1ee97b6e 100644 --- a/ocpp2.0.1/authorization/clear_cache.go +++ b/ocpp2.0.1/authorization/clear_cache.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Clear Cache (CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/availability/availability.go b/ocpp2.0.1/availability/availability.go index a903d258..4b53bc9a 100644 --- a/ocpp2.0.1/availability/availability.go +++ b/ocpp2.0.1/availability/availability.go @@ -2,7 +2,7 @@ // A CSMS can also instruct a charging station to change its availability. package availability -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Availability profile. type CSMSHandler interface { diff --git a/ocpp2.0.1/availability/change_availability.go b/ocpp2.0.1/availability/change_availability.go index 997434c1..5c68e009 100644 --- a/ocpp2.0.1/availability/change_availability.go +++ b/ocpp2.0.1/availability/change_availability.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Change Availability (CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/availability/heartbeat.go b/ocpp2.0.1/availability/heartbeat.go index f372478d..da87b3ac 100644 --- a/ocpp2.0.1/availability/heartbeat.go +++ b/ocpp2.0.1/availability/heartbeat.go @@ -3,7 +3,7 @@ package availability import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/availability/status_notification.go b/ocpp2.0.1/availability/status_notification.go index 9f4ae232..e463c271 100644 --- a/ocpp2.0.1/availability/status_notification.go +++ b/ocpp2.0.1/availability/status_notification.go @@ -3,7 +3,7 @@ package availability import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/charging_station.go b/ocpp2.0.1/charging_station.go index 31ef3831..60ea1ccf 100644 --- a/ocpp2.0.1/charging_station.go +++ b/ocpp2.0.1/charging_station.go @@ -4,26 +4,26 @@ import ( "fmt" "reflect" - "github.com/lorenzodonini/ocpp-go/internal/callbackqueue" - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/authorization" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/availability" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/data" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/display" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/iso15118" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/meter" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/remotecontrol" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/security" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/tariffcost" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/transactions" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" - "github.com/lorenzodonini/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/internal/callbackqueue" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/authorization" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/availability" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/data" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/display" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/iso15118" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/meter" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/remotecontrol" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/security" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/tariffcost" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/transactions" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocppj" ) type chargingStation struct { diff --git a/ocpp2.0.1/csms.go b/ocpp2.0.1/csms.go index 6d7b1684..d9fbe9a0 100644 --- a/ocpp2.0.1/csms.go +++ b/ocpp2.0.1/csms.go @@ -1,30 +1,31 @@ package ocpp2 import ( + "errors" "fmt" "reflect" - "github.com/lorenzodonini/ocpp-go/internal/callbackqueue" - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/authorization" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/availability" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/data" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/display" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/iso15118" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/meter" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/remotecontrol" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/security" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/tariffcost" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/transactions" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" - "github.com/lorenzodonini/ocpp-go/ocppj" - "github.com/lorenzodonini/ocpp-go/ws" + "github.com/xBlaz3kx/ocpp-go/internal/callbackqueue" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/authorization" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/availability" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/data" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/display" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/iso15118" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/meter" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/remotecontrol" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/security" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/tariffcost" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/transactions" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ws" ) type csms struct { @@ -49,15 +50,17 @@ type csms struct { errC chan error } -func newCSMS(server *ocppj.Server) csms { +func newCSMS(server *ocppj.Server) (csms, error) { if server == nil { - panic("server must not be nil") + return csms{}, errors.New("server must not be nil") } + server.SetDialect(ocpp.V2) + return csms{ server: server, callbackQueue: callbackqueue.New(), - } + }, nil } func (cs *csms) error(err error) { diff --git a/ocpp2.0.1/data/data.go b/ocpp2.0.1/data/data.go index c399f29f..d3d65842 100644 --- a/ocpp2.0.1/data/data.go +++ b/ocpp2.0.1/data/data.go @@ -1,7 +1,7 @@ // The data transfer functional block enables parties to add custom commands and extensions to OCPP 2.0. package data -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Data transfer profile. type CSMSHandler interface { diff --git a/ocpp2.0.1/data/data_transfer.go b/ocpp2.0.1/data/data_transfer.go index e82d18ed..d5dcd1db 100644 --- a/ocpp2.0.1/data/data_transfer.go +++ b/ocpp2.0.1/data/data_transfer.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Data Transfer (CS -> CSMS / CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/diagnostics/clear_variable_monitoring.go b/ocpp2.0.1/diagnostics/clear_variable_monitoring.go index ecec3149..d312760e 100644 --- a/ocpp2.0.1/diagnostics/clear_variable_monitoring.go +++ b/ocpp2.0.1/diagnostics/clear_variable_monitoring.go @@ -3,7 +3,7 @@ package diagnostics import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/diagnostics/customer_information.go b/ocpp2.0.1/diagnostics/customer_information.go index 97e3cc56..d2211c45 100644 --- a/ocpp2.0.1/diagnostics/customer_information.go +++ b/ocpp2.0.1/diagnostics/customer_information.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Customer Information (CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/diagnostics/diagnostics.go b/ocpp2.0.1/diagnostics/diagnostics.go index 20be8ed2..329b278c 100644 --- a/ocpp2.0.1/diagnostics/diagnostics.go +++ b/ocpp2.0.1/diagnostics/diagnostics.go @@ -1,7 +1,7 @@ // The diagnostics functional block contains OCPP 2.0 features than enable remote diagnostics of problems with a charging station. package diagnostics -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Diagnostics profile. type CSMSHandler interface { diff --git a/ocpp2.0.1/diagnostics/get_log.go b/ocpp2.0.1/diagnostics/get_log.go index 5b9fc4ea..ebd220cd 100644 --- a/ocpp2.0.1/diagnostics/get_log.go +++ b/ocpp2.0.1/diagnostics/get_log.go @@ -3,7 +3,7 @@ package diagnostics import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/diagnostics/get_monitoring_report.go b/ocpp2.0.1/diagnostics/get_monitoring_report.go index 98379b96..ea7d36d5 100644 --- a/ocpp2.0.1/diagnostics/get_monitoring_report.go +++ b/ocpp2.0.1/diagnostics/get_monitoring_report.go @@ -3,7 +3,7 @@ package diagnostics import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/diagnostics/log_status_notification.go b/ocpp2.0.1/diagnostics/log_status_notification.go index d3a949d0..f3d32110 100644 --- a/ocpp2.0.1/diagnostics/log_status_notification.go +++ b/ocpp2.0.1/diagnostics/log_status_notification.go @@ -3,7 +3,7 @@ package diagnostics import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/diagnostics/notify_customer_information.go b/ocpp2.0.1/diagnostics/notify_customer_information.go index 3c09908c..e4debc9b 100644 --- a/ocpp2.0.1/diagnostics/notify_customer_information.go +++ b/ocpp2.0.1/diagnostics/notify_customer_information.go @@ -3,7 +3,7 @@ package diagnostics import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Notify Customer Information (CS -> CSMS) -------------------- diff --git a/ocpp2.0.1/diagnostics/notify_event.go b/ocpp2.0.1/diagnostics/notify_event.go index 3e9127d5..3e7b156f 100644 --- a/ocpp2.0.1/diagnostics/notify_event.go +++ b/ocpp2.0.1/diagnostics/notify_event.go @@ -3,7 +3,7 @@ package diagnostics import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/diagnostics/notify_monitoring_report.go b/ocpp2.0.1/diagnostics/notify_monitoring_report.go index 1820604e..32f0aa37 100644 --- a/ocpp2.0.1/diagnostics/notify_monitoring_report.go +++ b/ocpp2.0.1/diagnostics/notify_monitoring_report.go @@ -3,7 +3,7 @@ package diagnostics import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Notify Monitoring Report (CS -> CSMS) -------------------- diff --git a/ocpp2.0.1/diagnostics/set_monitoring_base.go b/ocpp2.0.1/diagnostics/set_monitoring_base.go index 49096bbd..8fded4bc 100644 --- a/ocpp2.0.1/diagnostics/set_monitoring_base.go +++ b/ocpp2.0.1/diagnostics/set_monitoring_base.go @@ -3,7 +3,7 @@ package diagnostics import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/diagnostics/set_monitoring_level.go b/ocpp2.0.1/diagnostics/set_monitoring_level.go index 110ace67..8ddb4727 100644 --- a/ocpp2.0.1/diagnostics/set_monitoring_level.go +++ b/ocpp2.0.1/diagnostics/set_monitoring_level.go @@ -3,7 +3,7 @@ package diagnostics import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Set Monitoring Level (CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/diagnostics/set_variable_monitoring.go b/ocpp2.0.1/diagnostics/set_variable_monitoring.go index 14acf9c2..960e8c16 100644 --- a/ocpp2.0.1/diagnostics/set_variable_monitoring.go +++ b/ocpp2.0.1/diagnostics/set_variable_monitoring.go @@ -3,7 +3,7 @@ package diagnostics import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/diagnostics/types.go b/ocpp2.0.1/diagnostics/types.go index 3d94fb1a..6a2448b7 100644 --- a/ocpp2.0.1/diagnostics/types.go +++ b/ocpp2.0.1/diagnostics/types.go @@ -1,7 +1,7 @@ package diagnostics import ( - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/display/clear_display_message.go b/ocpp2.0.1/display/clear_display_message.go index f0057122..229a559a 100644 --- a/ocpp2.0.1/display/clear_display_message.go +++ b/ocpp2.0.1/display/clear_display_message.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Clear Display Message (CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/display/display.go b/ocpp2.0.1/display/display.go index ce7e4ccc..125f9b0a 100644 --- a/ocpp2.0.1/display/display.go +++ b/ocpp2.0.1/display/display.go @@ -1,7 +1,7 @@ // The display functional block contains OCPP 2.0 features for managing message that get displayed on a charging station. package display -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Display profile. type CSMSHandler interface { diff --git a/ocpp2.0.1/display/set_display_message.go b/ocpp2.0.1/display/set_display_message.go index 8f78510e..4b0dfc40 100644 --- a/ocpp2.0.1/display/set_display_message.go +++ b/ocpp2.0.1/display/set_display_message.go @@ -3,7 +3,7 @@ package display import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/display/types.go b/ocpp2.0.1/display/types.go index 250fa1c8..ff8dedaf 100644 --- a/ocpp2.0.1/display/types.go +++ b/ocpp2.0.1/display/types.go @@ -1,7 +1,7 @@ package display import ( - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/firmware/firmware.go b/ocpp2.0.1/firmware/firmware.go index 87f7c7aa..3dd1e786 100644 --- a/ocpp2.0.1/firmware/firmware.go +++ b/ocpp2.0.1/firmware/firmware.go @@ -1,7 +1,7 @@ // The firmware functional block contains OCPP 2.0 features that enable firmware updates on a charging station. package firmware -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Firmware profile. type CSMSHandler interface { diff --git a/ocpp2.0.1/firmware/firmware_status_notification.go b/ocpp2.0.1/firmware/firmware_status_notification.go index d18d1857..5d1f2204 100644 --- a/ocpp2.0.1/firmware/firmware_status_notification.go +++ b/ocpp2.0.1/firmware/firmware_status_notification.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Firmware Status Notification (CS -> CSMS) -------------------- diff --git a/ocpp2.0.1/firmware/publish_firmware.go b/ocpp2.0.1/firmware/publish_firmware.go index 56825cab..e2941d68 100644 --- a/ocpp2.0.1/firmware/publish_firmware.go +++ b/ocpp2.0.1/firmware/publish_firmware.go @@ -3,7 +3,7 @@ package firmware import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Publish Firmware (CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/firmware/publish_firmware_status_notification.go b/ocpp2.0.1/firmware/publish_firmware_status_notification.go index 3535dbf7..4848646c 100644 --- a/ocpp2.0.1/firmware/publish_firmware_status_notification.go +++ b/ocpp2.0.1/firmware/publish_firmware_status_notification.go @@ -3,7 +3,7 @@ package firmware import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/firmware/unpublish_firmware.go b/ocpp2.0.1/firmware/unpublish_firmware.go index b4820814..c4300285 100644 --- a/ocpp2.0.1/firmware/unpublish_firmware.go +++ b/ocpp2.0.1/firmware/unpublish_firmware.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Publish Firmware (CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/firmware/update_firmware.go b/ocpp2.0.1/firmware/update_firmware.go index eedea312..661f39c7 100644 --- a/ocpp2.0.1/firmware/update_firmware.go +++ b/ocpp2.0.1/firmware/update_firmware.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Publish Firmware (CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/iso15118/delete_certificate.go b/ocpp2.0.1/iso15118/delete_certificate.go index f2de20af..180170cc 100644 --- a/ocpp2.0.1/iso15118/delete_certificate.go +++ b/ocpp2.0.1/iso15118/delete_certificate.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Delete Certificate (CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/iso15118/get_15118ev_certificate.go b/ocpp2.0.1/iso15118/get_15118ev_certificate.go index 9eb53c37..2abae416 100644 --- a/ocpp2.0.1/iso15118/get_15118ev_certificate.go +++ b/ocpp2.0.1/iso15118/get_15118ev_certificate.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Get 15118EV Certificate (CS -> CSMS) -------------------- diff --git a/ocpp2.0.1/iso15118/get_certificate_status.go b/ocpp2.0.1/iso15118/get_certificate_status.go index 093832f0..7b1c171b 100644 --- a/ocpp2.0.1/iso15118/get_certificate_status.go +++ b/ocpp2.0.1/iso15118/get_certificate_status.go @@ -3,7 +3,7 @@ package iso15118 import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Get Certificate Status (CS -> CSMS) -------------------- diff --git a/ocpp2.0.1/iso15118/get_installed_certificate_ids.go b/ocpp2.0.1/iso15118/get_installed_certificate_ids.go index 58271d02..fc865aec 100644 --- a/ocpp2.0.1/iso15118/get_installed_certificate_ids.go +++ b/ocpp2.0.1/iso15118/get_installed_certificate_ids.go @@ -3,7 +3,7 @@ package iso15118 import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/iso15118/install_certificate.go b/ocpp2.0.1/iso15118/install_certificate.go index 7ce446b6..36a75002 100644 --- a/ocpp2.0.1/iso15118/install_certificate.go +++ b/ocpp2.0.1/iso15118/install_certificate.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Clear Display (CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/iso15118/iso_15118.go b/ocpp2.0.1/iso15118/iso_15118.go index 46866bfa..18542b0e 100644 --- a/ocpp2.0.1/iso15118/iso_15118.go +++ b/ocpp2.0.1/iso15118/iso_15118.go @@ -5,7 +5,7 @@ // - support for certificate-based authentication and authorization at the charging station, i.e. plug and charge package iso15118 -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 ISO 15118 profile. type CSMSHandler interface { diff --git a/ocpp2.0.1/localauth/local_auth_list.go b/ocpp2.0.1/localauth/local_auth_list.go index 90467c67..c3fce031 100644 --- a/ocpp2.0.1/localauth/local_auth_list.go +++ b/ocpp2.0.1/localauth/local_auth_list.go @@ -2,7 +2,7 @@ // Local lists are used for offline and generally optimized authorization. package localauth -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Local Authorization List profile. type CSMSHandler interface { diff --git a/ocpp2.0.1/localauth/send_local_list.go b/ocpp2.0.1/localauth/send_local_list.go index 06550bb8..8635187a 100644 --- a/ocpp2.0.1/localauth/send_local_list.go +++ b/ocpp2.0.1/localauth/send_local_list.go @@ -3,7 +3,7 @@ package localauth import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/meter/meter.go b/ocpp2.0.1/meter/meter.go index b693da8f..3796539c 100644 --- a/ocpp2.0.1/meter/meter.go +++ b/ocpp2.0.1/meter/meter.go @@ -1,7 +1,7 @@ // The Meter values functional block contains OCPP 2.0 features for sending meter values to the CSMS. package meter -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Meter values profile. type CSMSHandler interface { diff --git a/ocpp2.0.1/meter/meter_values.go b/ocpp2.0.1/meter/meter_values.go index 09500dc3..8e67ba2b 100644 --- a/ocpp2.0.1/meter/meter_values.go +++ b/ocpp2.0.1/meter/meter_values.go @@ -3,7 +3,7 @@ package meter import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Meter Values (CS -> CSMS) -------------------- diff --git a/ocpp2.0.1/provisioning/boot_notification.go b/ocpp2.0.1/provisioning/boot_notification.go index 9bdb276d..3f846413 100644 --- a/ocpp2.0.1/provisioning/boot_notification.go +++ b/ocpp2.0.1/provisioning/boot_notification.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Boot Notification (CS -> CSMS) -------------------- diff --git a/ocpp2.0.1/provisioning/get_base_report.go b/ocpp2.0.1/provisioning/get_base_report.go index 3217ca33..184bc9a1 100644 --- a/ocpp2.0.1/provisioning/get_base_report.go +++ b/ocpp2.0.1/provisioning/get_base_report.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Get Base Report (CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/provisioning/get_report.go b/ocpp2.0.1/provisioning/get_report.go index 873334ac..138c2cd9 100644 --- a/ocpp2.0.1/provisioning/get_report.go +++ b/ocpp2.0.1/provisioning/get_report.go @@ -3,7 +3,7 @@ package provisioning import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/provisioning/get_variables.go b/ocpp2.0.1/provisioning/get_variables.go index 26df1c2c..e212e08c 100644 --- a/ocpp2.0.1/provisioning/get_variables.go +++ b/ocpp2.0.1/provisioning/get_variables.go @@ -3,7 +3,7 @@ package provisioning import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/provisioning/notify_report.go b/ocpp2.0.1/provisioning/notify_report.go index 665160e5..d779e374 100644 --- a/ocpp2.0.1/provisioning/notify_report.go +++ b/ocpp2.0.1/provisioning/notify_report.go @@ -3,7 +3,7 @@ package provisioning import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/provisioning/provisioning.go b/ocpp2.0.1/provisioning/provisioning.go index 3bf951cc..00005f80 100644 --- a/ocpp2.0.1/provisioning/provisioning.go +++ b/ocpp2.0.1/provisioning/provisioning.go @@ -2,7 +2,7 @@ // Additionally, it contains features for retrieving information about the configuration of Charging Stations, make changes to the configuration, resetting it etc. package provisioning -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Provisioning profile. type CSMSHandler interface { diff --git a/ocpp2.0.1/provisioning/reset.go b/ocpp2.0.1/provisioning/reset.go index 86d3bc66..f8699a38 100644 --- a/ocpp2.0.1/provisioning/reset.go +++ b/ocpp2.0.1/provisioning/reset.go @@ -3,7 +3,7 @@ package provisioning import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/provisioning/set_network_profile.go b/ocpp2.0.1/provisioning/set_network_profile.go index 867d7bf1..75e273f9 100644 --- a/ocpp2.0.1/provisioning/set_network_profile.go +++ b/ocpp2.0.1/provisioning/set_network_profile.go @@ -3,7 +3,7 @@ package provisioning import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/provisioning/set_variables.go b/ocpp2.0.1/provisioning/set_variables.go index dfc100de..40239cc1 100644 --- a/ocpp2.0.1/provisioning/set_variables.go +++ b/ocpp2.0.1/provisioning/set_variables.go @@ -3,7 +3,7 @@ package provisioning import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/remotecontrol/remote_control.go b/ocpp2.0.1/remotecontrol/remote_control.go index fa33933f..0db5c8f6 100644 --- a/ocpp2.0.1/remotecontrol/remote_control.go +++ b/ocpp2.0.1/remotecontrol/remote_control.go @@ -1,7 +1,7 @@ // The Remote control functional block contains OCPP 2.0 features for remote-control management from the CSMS. package remotecontrol -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Remote control profile. type CSMSHandler interface { diff --git a/ocpp2.0.1/remotecontrol/request_start_transaction.go b/ocpp2.0.1/remotecontrol/request_start_transaction.go index cbf92bd0..f73d22ac 100644 --- a/ocpp2.0.1/remotecontrol/request_start_transaction.go +++ b/ocpp2.0.1/remotecontrol/request_start_transaction.go @@ -3,7 +3,7 @@ package remotecontrol import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/remotecontrol/request_stop_transaction.go b/ocpp2.0.1/remotecontrol/request_stop_transaction.go index cf0ddd1d..f12030f6 100644 --- a/ocpp2.0.1/remotecontrol/request_stop_transaction.go +++ b/ocpp2.0.1/remotecontrol/request_stop_transaction.go @@ -3,7 +3,7 @@ package remotecontrol import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Request Start Transaction (CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/remotecontrol/trigger_message.go b/ocpp2.0.1/remotecontrol/trigger_message.go index ead9347c..f54c7a78 100644 --- a/ocpp2.0.1/remotecontrol/trigger_message.go +++ b/ocpp2.0.1/remotecontrol/trigger_message.go @@ -3,7 +3,7 @@ package remotecontrol import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/remotecontrol/unlock_connector.go b/ocpp2.0.1/remotecontrol/unlock_connector.go index 07035285..c53a3bee 100644 --- a/ocpp2.0.1/remotecontrol/unlock_connector.go +++ b/ocpp2.0.1/remotecontrol/unlock_connector.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Trigger Message (CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/reservation/cancel_reservation.go b/ocpp2.0.1/reservation/cancel_reservation.go index e865ccea..57250e53 100644 --- a/ocpp2.0.1/reservation/cancel_reservation.go +++ b/ocpp2.0.1/reservation/cancel_reservation.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Cancel Reservation (CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/reservation/reservation.go b/ocpp2.0.1/reservation/reservation.go index 63cfd4ac..e255344c 100644 --- a/ocpp2.0.1/reservation/reservation.go +++ b/ocpp2.0.1/reservation/reservation.go @@ -2,7 +2,7 @@ package reservation import ( - "github.com/lorenzodonini/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp" ) // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Reservation profile. diff --git a/ocpp2.0.1/reservation/reservation_status_update.go b/ocpp2.0.1/reservation/reservation_status_update.go index aa9e7275..db67b225 100644 --- a/ocpp2.0.1/reservation/reservation_status_update.go +++ b/ocpp2.0.1/reservation/reservation_status_update.go @@ -3,7 +3,7 @@ package reservation import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/reservation/reserve_now.go b/ocpp2.0.1/reservation/reserve_now.go index bdac41fc..ee5c5f21 100644 --- a/ocpp2.0.1/reservation/reserve_now.go +++ b/ocpp2.0.1/reservation/reserve_now.go @@ -3,7 +3,7 @@ package reservation import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/security/certificate_signed.go b/ocpp2.0.1/security/certificate_signed.go index 7bf62a79..36bc82ec 100644 --- a/ocpp2.0.1/security/certificate_signed.go +++ b/ocpp2.0.1/security/certificate_signed.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Certificate Signed (CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/security/security.go b/ocpp2.0.1/security/security.go index a3c23a0b..dd0ca327 100644 --- a/ocpp2.0.1/security/security.go +++ b/ocpp2.0.1/security/security.go @@ -1,7 +1,7 @@ // The security functional block contains OCPP 2.0 features aimed at providing E2E security between a CSMS and a Charging station. package security -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Security profile. type CSMSHandler interface { diff --git a/ocpp2.0.1/security/security_event_notification.go b/ocpp2.0.1/security/security_event_notification.go index 0896beea..d3449110 100644 --- a/ocpp2.0.1/security/security_event_notification.go +++ b/ocpp2.0.1/security/security_event_notification.go @@ -3,7 +3,7 @@ package security import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Security Event Notification Status (CS -> CSMS) -------------------- diff --git a/ocpp2.0.1/security/sign_certificate.go b/ocpp2.0.1/security/sign_certificate.go index b6c63eaa..96be5f1d 100644 --- a/ocpp2.0.1/security/sign_certificate.go +++ b/ocpp2.0.1/security/sign_certificate.go @@ -3,7 +3,7 @@ package security import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Sign Certificate (CS -> CSMS) -------------------- diff --git a/ocpp2.0.1/smartcharging/clear_charging_profile.go b/ocpp2.0.1/smartcharging/clear_charging_profile.go index a366d132..0f476c91 100644 --- a/ocpp2.0.1/smartcharging/clear_charging_profile.go +++ b/ocpp2.0.1/smartcharging/clear_charging_profile.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Clear Charging Profile (CSMS -> CS) -------------------- diff --git a/ocpp2.0.1/smartcharging/cleared_charging_limit.go b/ocpp2.0.1/smartcharging/cleared_charging_limit.go index a6966877..b896c676 100644 --- a/ocpp2.0.1/smartcharging/cleared_charging_limit.go +++ b/ocpp2.0.1/smartcharging/cleared_charging_limit.go @@ -3,7 +3,7 @@ package smartcharging import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Cleared Charging Limit (CS -> CSMS) -------------------- diff --git a/ocpp2.0.1/smartcharging/get_charging_profiles.go b/ocpp2.0.1/smartcharging/get_charging_profiles.go index 5f78e526..11070803 100644 --- a/ocpp2.0.1/smartcharging/get_charging_profiles.go +++ b/ocpp2.0.1/smartcharging/get_charging_profiles.go @@ -5,7 +5,7 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Get Charging Profiles (CSMS -> Charging Station) -------------------- diff --git a/ocpp2.0.1/smartcharging/get_composite_schedule.go b/ocpp2.0.1/smartcharging/get_composite_schedule.go index 0827b85a..e3ce5e27 100644 --- a/ocpp2.0.1/smartcharging/get_composite_schedule.go +++ b/ocpp2.0.1/smartcharging/get_composite_schedule.go @@ -3,7 +3,7 @@ package smartcharging import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/smartcharging/notify_charging_limit.go b/ocpp2.0.1/smartcharging/notify_charging_limit.go index 143a2684..30091b90 100644 --- a/ocpp2.0.1/smartcharging/notify_charging_limit.go +++ b/ocpp2.0.1/smartcharging/notify_charging_limit.go @@ -3,7 +3,7 @@ package smartcharging import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Notify Charging Limit (CS -> CSMS) -------------------- diff --git a/ocpp2.0.1/smartcharging/notify_ev_charging_needs.go b/ocpp2.0.1/smartcharging/notify_ev_charging_needs.go index a83e7faf..74cc1d5a 100644 --- a/ocpp2.0.1/smartcharging/notify_ev_charging_needs.go +++ b/ocpp2.0.1/smartcharging/notify_ev_charging_needs.go @@ -3,7 +3,7 @@ package smartcharging import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/smartcharging/notify_ev_charging_schedule.go b/ocpp2.0.1/smartcharging/notify_ev_charging_schedule.go index 6c8b6fdd..52368c0f 100644 --- a/ocpp2.0.1/smartcharging/notify_ev_charging_schedule.go +++ b/ocpp2.0.1/smartcharging/notify_ev_charging_schedule.go @@ -3,7 +3,7 @@ package smartcharging import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Notify EV Charging Schedule (CS -> CSMS) -------------------- diff --git a/ocpp2.0.1/smartcharging/report_charging_profiles.go b/ocpp2.0.1/smartcharging/report_charging_profiles.go index c1f8b998..2a24d5b6 100644 --- a/ocpp2.0.1/smartcharging/report_charging_profiles.go +++ b/ocpp2.0.1/smartcharging/report_charging_profiles.go @@ -3,7 +3,7 @@ package smartcharging import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // -------------------- Report Charging Profiles (CS -> CSMS) -------------------- diff --git a/ocpp2.0.1/smartcharging/set_charging_profile.go b/ocpp2.0.1/smartcharging/set_charging_profile.go index c1adcf86..d64c4bb2 100644 --- a/ocpp2.0.1/smartcharging/set_charging_profile.go +++ b/ocpp2.0.1/smartcharging/set_charging_profile.go @@ -3,7 +3,7 @@ package smartcharging import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/smartcharging/smart_charging.go b/ocpp2.0.1/smartcharging/smart_charging.go index 2c6a3d3f..46553a86 100644 --- a/ocpp2.0.1/smartcharging/smart_charging.go +++ b/ocpp2.0.1/smartcharging/smart_charging.go @@ -2,7 +2,7 @@ package smartcharging import ( - "github.com/lorenzodonini/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp" ) // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Smart charging profile. diff --git a/ocpp2.0.1/tariffcost/tariff_cost.go b/ocpp2.0.1/tariffcost/tariff_cost.go index d0d15cc9..04f6433e 100644 --- a/ocpp2.0.1/tariffcost/tariff_cost.go +++ b/ocpp2.0.1/tariffcost/tariff_cost.go @@ -1,7 +1,7 @@ // The authorization functional block contains OCPP 2.0 features that show tariff and costs to an EV driver, when supported by the charging station. package tariffcost -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Tariff and cost profile. type CSMSHandler interface { diff --git a/ocpp2.0.1/transactions/transaction_event.go b/ocpp2.0.1/transactions/transaction_event.go index e759d179..6dda0e94 100644 --- a/ocpp2.0.1/transactions/transaction_event.go +++ b/ocpp2.0.1/transactions/transaction_event.go @@ -3,7 +3,7 @@ package transactions import ( "reflect" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" "gopkg.in/go-playground/validator.v9" ) diff --git a/ocpp2.0.1/transactions/transactions.go b/ocpp2.0.1/transactions/transactions.go index 59dfc758..5499da10 100644 --- a/ocpp2.0.1/transactions/transactions.go +++ b/ocpp2.0.1/transactions/transactions.go @@ -1,7 +1,7 @@ // The transactions functional block contains OCPP 2.0 features related to OCPP transactions. package transactions -import "github.com/lorenzodonini/ocpp-go/ocpp" +import "github.com/xBlaz3kx/ocpp-go/ocpp" // Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Transactions profile. type CSMSHandler interface { diff --git a/ocpp2.0.1/types/types.go b/ocpp2.0.1/types/types.go index 017bf1c2..274a8616 100644 --- a/ocpp2.0.1/types/types.go +++ b/ocpp2.0.1/types/types.go @@ -4,7 +4,7 @@ package types import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ocppj" ) const ( diff --git a/ocpp2.0.1/v2.go b/ocpp2.0.1/v2.go index 3bc38ac3..a91be13f 100644 --- a/ocpp2.0.1/v2.go +++ b/ocpp2.0.1/v2.go @@ -5,27 +5,28 @@ import ( "crypto/tls" "net" - "github.com/lorenzodonini/ocpp-go/internal/callbackqueue" - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/authorization" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/availability" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/data" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/display" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/iso15118" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/meter" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/remotecontrol" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/security" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/tariffcost" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/transactions" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" - "github.com/lorenzodonini/ocpp-go/ocppj" - "github.com/lorenzodonini/ocpp-go/ws" + "github.com/xBlaz3kx/ocpp-go/internal/callbackqueue" + "github.com/xBlaz3kx/ocpp-go/logging" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/authorization" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/availability" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/data" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/display" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/iso15118" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/meter" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/remotecontrol" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/security" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/tariffcost" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/transactions" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ws" ) type ChargingStationConnection interface { @@ -208,16 +209,38 @@ type ChargingStation interface { // // For more advanced options, or if a custom networking/occpj layer is required, // please refer to ocppj.Client and ws.Client. -func NewChargingStation(id string, endpoint *ocppj.Client, client ws.Client) ChargingStation { +func NewChargingStation(id string, endpoint *ocppj.Client, client ws.Client, logger logging.Logger) (ChargingStation, error) { if client == nil { client = ws.NewClient() } client.SetRequestedSubProtocol(types.V201Subprotocol) + var err error if endpoint == nil { - dispatcher := ocppj.NewDefaultClientDispatcher(ocppj.NewFIFOClientQueue(0)) - endpoint = ocppj.NewClient(id, client, dispatcher, nil, authorization.Profile, availability.Profile, data.Profile, diagnostics.Profile, display.Profile, firmware.Profile, iso15118.Profile, localauth.Profile, meter.Profile, provisioning.Profile, remotecontrol.Profile, reservation.Profile, security.Profile, smartcharging.Profile, tariffcost.Profile, transactions.Profile) + dispatcher := ocppj.NewDefaultClientDispatcher(ocppj.NewFIFOClientQueue(0), logger) + endpoint, err = ocppj.NewClient(id, client, dispatcher, nil, logger, + authorization.Profile, + availability.Profile, + data.Profile, + diagnostics.Profile, + display.Profile, + firmware.Profile, + iso15118.Profile, + localauth.Profile, + meter.Profile, + provisioning.Profile, + remotecontrol.Profile, + reservation.Profile, + security.Profile, + smartcharging.Profile, + tariffcost.Profile, + transactions.Profile, + ) + if err != nil { + return nil, err + } } + endpoint.SetDialect(ocpp.V2) cs := chargingStation{ @@ -237,7 +260,8 @@ func NewChargingStation(id string, endpoint *ocppj.Client, client ws.Client) Cha cs.errorHandler <- err }) cs.client.SetRequestHandler(cs.handleIncomingRequest) - return &cs + + return &cs, nil } // -------------------- v2.0 CSMS -------------------- @@ -415,13 +439,16 @@ type CSMS interface { // If you need a TLS server, you may use the following: // // csms := NewCSMS(nil, ws.NewServer(ws.WithServerTLSConfig("certificatePath", "privateKeyPath", nil))) -func NewCSMS(endpoint *ocppj.Server, server ws.Server) CSMS { +func NewCSMS(endpoint *ocppj.Server, server ws.Server, logger logging.Logger) (CSMS, error) { if server == nil { server = ws.NewServer() } + server.AddSupportedSubprotocol(types.V201Subprotocol) + + var err error if endpoint == nil { - endpoint = ocppj.NewServer(server, nil, nil, + endpoint, err = ocppj.NewServer(server, nil, nil, logger, authorization.Profile, availability.Profile, data.Profile, @@ -439,8 +466,16 @@ func NewCSMS(endpoint *ocppj.Server, server ws.Server) CSMS { tariffcost.Profile, transactions.Profile, ) + if err != nil { + return nil, err + } + } + + cs, err := newCSMS(endpoint) + if err != nil { + return nil, err } - cs := newCSMS(endpoint) + cs.server.SetRequestHandler(func(client ws.Channel, request ocpp.Request, requestId string, action string) { cs.handleIncomingRequest(client, request, requestId, action) }) @@ -453,5 +488,6 @@ func NewCSMS(endpoint *ocppj.Server, server ws.Server) CSMS { cs.server.SetCanceledRequestHandler(func(clientID string, requestID string, request ocpp.Request, err *ocpp.Error) { cs.handleCanceledRequest(clientID, request, err) }) - return &cs + + return &cs, nil } diff --git a/ocpp2.0.1_test/authorize_test.go b/ocpp2.0.1_test/authorize_test.go index 2f6f08ca..6bb2bd1e 100644 --- a/ocpp2.0.1_test/authorize_test.go +++ b/ocpp2.0.1_test/authorize_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/authorization" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/authorization" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestAuthorizeRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {authorization.AuthorizeRequest{Certificate: "deadc0de", IdToken: types.IdToken{IdToken: "1234", Type: types.IdTokenTypeKeyCode, AdditionalInfo: []types.AdditionalInfo{{AdditionalIdToken: "0000", Type: "someType"}}}, CertificateHashData: []types.OCSPRequestDataType{{SerialNumber: "serial0", HashAlgorithm: types.SHA256, IssuerNameHash: "hash0", IssuerKeyHash: "hash1", ResponderURL: "www.someurl.com"}}}, true}, {authorization.AuthorizeRequest{Certificate: "deadc0de", IdToken: types.IdToken{IdToken: "1234", Type: types.IdTokenTypeKeyCode, AdditionalInfo: []types.AdditionalInfo{{AdditionalIdToken: "0000", Type: "someType"}}}}, true}, @@ -26,11 +23,10 @@ func (suite *OcppV2TestSuite) TestAuthorizeRequestValidation() { {authorization.AuthorizeRequest{Certificate: "deadc0de", IdToken: types.IdToken{Type: types.IdTokenTypeKeyCode, AdditionalInfo: []types.AdditionalInfo{{AdditionalIdToken: "0000", Type: "someType"}}}, CertificateHashData: []types.OCSPRequestDataType{{HashAlgorithm: types.SHA256, IssuerNameHash: "hash0", IssuerKeyHash: "hash1"}}}, false}, {authorization.AuthorizeRequest{Certificate: "deadc0de", IdToken: types.IdToken{Type: types.IdTokenTypeKeyCode, AdditionalInfo: []types.AdditionalInfo{{AdditionalIdToken: "0000", Type: "someType"}}}, CertificateHashData: []types.OCSPRequestDataType{{SerialNumber: "s0", HashAlgorithm: types.SHA256, IssuerNameHash: "h0", IssuerKeyHash: "h0.1"}, {SerialNumber: "s1", HashAlgorithm: types.SHA256, IssuerNameHash: "h1", IssuerKeyHash: "h1.1"}, {SerialNumber: "s2", HashAlgorithm: types.SHA256, IssuerNameHash: "h2", IssuerKeyHash: "h2.1"}, {SerialNumber: "s3", HashAlgorithm: types.SHA256, IssuerNameHash: "h3", IssuerKeyHash: "h3.1"}, {SerialNumber: "s4", HashAlgorithm: types.SHA256, IssuerNameHash: "h4", IssuerKeyHash: "h4.1"}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestAuthorizeConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {authorization.AuthorizeResponse{CertificateStatus: authorization.CertificateStatusAccepted, IdTokenInfo: types.IdTokenInfo{Status: types.AuthorizationStatusAccepted}}, true}, {authorization.AuthorizeResponse{CertificateStatus: authorization.CertificateStatusAccepted, IdTokenInfo: types.IdTokenInfo{Status: types.AuthorizationStatusAccepted}}, true}, @@ -39,11 +35,10 @@ func (suite *OcppV2TestSuite) TestAuthorizeConfirmationValidation() { {authorization.AuthorizeResponse{CertificateStatus: "invalidCertificateStatus", IdTokenInfo: types.IdTokenInfo{Status: types.AuthorizationStatusAccepted}}, false}, {authorization.AuthorizeResponse{CertificateStatus: authorization.CertificateStatusAccepted, IdTokenInfo: types.IdTokenInfo{Status: "invalidTokenInfoStatus"}}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestAuthorizeE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -66,34 +61,34 @@ func (suite *OcppV2TestSuite) TestAuthorizeE2EMocked() { handler := &MockCSMSAuthorizationHandler{} handler.On("OnAuthorize", mock.AnythingOfType("string"), mock.Anything).Return(authorizeConfirmation, nil).Run(func(args mock.Arguments) { request := args.Get(1).(*authorization.AuthorizeRequest) - assert.Equal(t, certificate, request.Certificate) - assert.Equal(t, idToken.IdToken, request.IdToken.IdToken) - assert.Equal(t, idToken.Type, request.IdToken.Type) - require.Len(t, request.IdToken.AdditionalInfo, 1) - assert.Equal(t, idToken.AdditionalInfo[0].AdditionalIdToken, request.IdToken.AdditionalInfo[0].AdditionalIdToken) - assert.Equal(t, idToken.AdditionalInfo[0].Type, request.IdToken.AdditionalInfo[0].Type) - require.Len(t, request.CertificateHashData, 1) - assert.Equal(t, certHashData.HashAlgorithm, request.CertificateHashData[0].HashAlgorithm) - assert.Equal(t, certHashData.IssuerNameHash, request.CertificateHashData[0].IssuerNameHash) - assert.Equal(t, certHashData.IssuerKeyHash, request.CertificateHashData[0].IssuerKeyHash) - assert.Equal(t, certHashData.SerialNumber, request.CertificateHashData[0].SerialNumber) - assert.Equal(t, certHashData.ResponderURL, request.CertificateHashData[0].ResponderURL) + suite.Equal(certificate, request.Certificate) + suite.Equal(idToken.IdToken, request.IdToken.IdToken) + suite.Equal(idToken.Type, request.IdToken.Type) + suite.Require().Len(request.IdToken.AdditionalInfo, 1) + suite.Equal(idToken.AdditionalInfo[0].AdditionalIdToken, request.IdToken.AdditionalInfo[0].AdditionalIdToken) + suite.Equal(idToken.AdditionalInfo[0].Type, request.IdToken.AdditionalInfo[0].Type) + suite.Require().Len(request.CertificateHashData, 1) + suite.Equal(certHashData.HashAlgorithm, request.CertificateHashData[0].HashAlgorithm) + suite.Equal(certHashData.IssuerNameHash, request.CertificateHashData[0].IssuerNameHash) + suite.Equal(certHashData.IssuerKeyHash, request.CertificateHashData[0].IssuerKeyHash) + suite.Equal(certHashData.SerialNumber, request.CertificateHashData[0].SerialNumber) + suite.Equal(certHashData.ResponderURL, request.CertificateHashData[0].ResponderURL) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: responseRaw, forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: requestRaw, forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) response, err := suite.chargingStation.Authorize(idToken.IdToken, idToken.Type, func(request *authorization.AuthorizeRequest) { request.IdToken.AdditionalInfo = []types.AdditionalInfo{additionalInfo} request.Certificate = certificate request.CertificateHashData = []types.OCSPRequestDataType{certHashData} }) - require.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, certificateStatus, response.CertificateStatus) - assert.Equal(t, status, response.IdTokenInfo.Status) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Equal(certificateStatus, response.CertificateStatus) + suite.Equal(status, response.IdTokenInfo.Status) } func (suite *OcppV2TestSuite) TestAuthorizeInvalidEndpoint() { diff --git a/ocpp2.0.1_test/boot_notification_test.go b/ocpp2.0.1_test/boot_notification_test.go index d342a625..489eee36 100644 --- a/ocpp2.0.1_test/boot_notification_test.go +++ b/ocpp2.0.1_test/boot_notification_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Tests func (suite *OcppV2TestSuite) TestBootNotificationRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {provisioning.BootNotificationRequest{Reason: provisioning.BootReasonPowerUp, ChargingStation: provisioning.ChargingStationType{SerialNumber: "number", Model: "test", VendorName: "test", FirmwareVersion: "version", Modem: &provisioning.ModemType{Iccid: "test", Imsi: "test"}}}, true}, {provisioning.BootNotificationRequest{Reason: provisioning.BootReasonPowerUp, ChargingStation: provisioning.ChargingStationType{SerialNumber: "number", Model: "test", VendorName: "test", FirmwareVersion: "version", Modem: &provisioning.ModemType{Iccid: "test"}}}, true}, @@ -34,11 +31,10 @@ func (suite *OcppV2TestSuite) TestBootNotificationRequestValidation() { {provisioning.BootNotificationRequest{Reason: provisioning.BootReasonPowerUp, ChargingStation: provisioning.ChargingStationType{Model: "test", VendorName: "test", Modem: &provisioning.ModemType{Imsi: ">20.................."}}}, false}, {provisioning.BootNotificationRequest{Reason: "invalidReason", ChargingStation: provisioning.ChargingStationType{Model: "test", VendorName: "test"}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestBootNotificationConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {provisioning.BootNotificationResponse{CurrentTime: types.NewDateTime(time.Now()), Interval: 60, Status: provisioning.RegistrationStatusAccepted}, true}, {provisioning.BootNotificationResponse{CurrentTime: types.NewDateTime(time.Now()), Status: provisioning.RegistrationStatusAccepted}, true}, @@ -47,11 +43,10 @@ func (suite *OcppV2TestSuite) TestBootNotificationConfirmationValidation() { {provisioning.BootNotificationResponse{CurrentTime: types.NewDateTime(time.Now()), Interval: 60}, false}, {provisioning.BootNotificationResponse{Interval: 60, Status: provisioning.RegistrationStatusAccepted}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestBootNotificationE2EMocked() { - t := suite.T() wsId := "test_id" messageId := "1234" wsUrl := "someUrl" @@ -69,22 +64,22 @@ func (suite *OcppV2TestSuite) TestBootNotificationE2EMocked() { handler := &MockCSMSProvisioningHandler{} handler.On("OnBootNotification", mock.AnythingOfType("string"), mock.Anything).Return(bootNotificationConfirmation, nil).Run(func(args mock.Arguments) { request := args.Get(1).(*provisioning.BootNotificationRequest) - assert.Equal(t, reason, request.Reason) - assert.Equal(t, chargePointVendor, request.ChargingStation.VendorName) - assert.Equal(t, chargePointModel, request.ChargingStation.Model) + suite.Equal(reason, request.Reason) + suite.Equal(chargePointVendor, request.ChargingStation.VendorName) + suite.Equal(chargePointModel, request.ChargingStation.Model) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) confirmation, err := suite.chargingStation.BootNotification(reason, chargePointModel, chargePointVendor) - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, registrationStatus, confirmation.Status) - assert.Equal(t, interval, confirmation.Interval) - assertDateTimeEquality(t, currentTime, confirmation.CurrentTime) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(registrationStatus, confirmation.Status) + suite.Equal(interval, confirmation.Interval) + assertDateTimeEquality(suite, currentTime, confirmation.CurrentTime) } func (suite *OcppV2TestSuite) TestBootNotificationInvalidEndpoint() { diff --git a/ocpp2.0.1_test/cancel_reservation_test.go b/ocpp2.0.1_test/cancel_reservation_test.go index 0ae852e1..4fe1b22e 100644 --- a/ocpp2.0.1_test/cancel_reservation_test.go +++ b/ocpp2.0.1_test/cancel_reservation_test.go @@ -3,27 +3,23 @@ package ocpp2_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" ) // Test func (suite *OcppV2TestSuite) TestCancelReservationRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {reservation.CancelReservationRequest{ReservationID: 42}, true}, {reservation.CancelReservationRequest{}, true}, {reservation.CancelReservationRequest{ReservationID: -1}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestCancelReservationConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {reservation.CancelReservationResponse{Status: reservation.CancelReservationStatusAccepted, StatusInfo: types.NewStatusInfo("200", "ok")}, true}, {reservation.CancelReservationResponse{Status: reservation.CancelReservationStatusAccepted}, true}, @@ -31,11 +27,10 @@ func (suite *OcppV2TestSuite) TestCancelReservationConfirmationValidation() { {reservation.CancelReservationResponse{}, false}, {reservation.CancelReservationResponse{Status: reservation.CancelReservationStatusAccepted, StatusInfo: types.NewStatusInfo("", "")}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestCancelReservationE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -49,25 +44,25 @@ func (suite *OcppV2TestSuite) TestCancelReservationE2EMocked() { handler := &MockChargingStationReservationHandler{} handler.On("OnCancelReservation", mock.Anything).Return(cancelReservationConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*reservation.CancelReservationRequest) - require.True(t, ok) - assert.Equal(t, reservationId, request.ReservationID) + suite.Require().True(ok) + suite.Equal(reservationId, request.ReservationID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.CancelReservation(wsId, func(confirmation *reservation.CancelReservationResponse, err error) { - require.Nil(t, err) - assert.NotNil(t, confirmation) - require.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.NotNil(confirmation) + suite.Require().Equal(status, confirmation.Status) resultChannel <- true }, reservationId) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestCancelReservationInvalidEndpoint() { diff --git a/ocpp2.0.1_test/certificate_signed_test.go b/ocpp2.0.1_test/certificate_signed_test.go index adea66b7..8138cf07 100644 --- a/ocpp2.0.1_test/certificate_signed_test.go +++ b/ocpp2.0.1_test/certificate_signed_test.go @@ -3,16 +3,13 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/security" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/security" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) func (suite *OcppV2TestSuite) TestCertificateSignedRequestValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {security.CertificateSignedRequest{CertificateChain: "sampleCert", TypeOfCertificate: types.ChargingStationCert}, true}, {security.CertificateSignedRequest{CertificateChain: "sampleCert"}, true}, @@ -21,11 +18,10 @@ func (suite *OcppV2TestSuite) TestCertificateSignedRequestValidation() { {security.CertificateSignedRequest{CertificateChain: newLongString(100001)}, false}, {security.CertificateSignedRequest{CertificateChain: "sampleCert", TypeOfCertificate: "invalidCertificateType"}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestCertificateSignedConfirmationValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {security.CertificateSignedResponse{Status: security.CertificateSignedStatusAccepted, StatusInfo: types.NewStatusInfo("200", "ok")}, true}, {security.CertificateSignedResponse{Status: security.CertificateSignedStatusAccepted}, true}, @@ -34,12 +30,11 @@ func (suite *OcppV2TestSuite) TestCertificateSignedConfirmationValidation() { {security.CertificateSignedResponse{Status: security.CertificateSignedStatusAccepted, StatusInfo: types.NewStatusInfo("", "")}, false}, {security.CertificateSignedResponse{}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } // Test func (suite *OcppV2TestSuite) TestCertificateSignedE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -55,28 +50,28 @@ func (suite *OcppV2TestSuite) TestCertificateSignedE2EMocked() { handler := &MockChargingStationSecurityHandler{} handler.On("OnCertificateSigned", mock.Anything).Return(certificateSignedConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*security.CertificateSignedRequest) - require.True(t, ok) - assert.Equal(t, certificateChain, request.CertificateChain) - assert.Equal(t, certificateType, request.TypeOfCertificate) + suite.Require().True(ok) + suite.Equal(certificateChain, request.CertificateChain) + suite.Equal(certificateType, request.TypeOfCertificate) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.CertificateSigned(wsId, func(confirmation *security.CertificateSignedResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, certificateChain, func(request *security.CertificateSignedRequest) { request.TypeOfCertificate = certificateType }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestCertificateSignedInvalidEndpoint() { diff --git a/ocpp2.0.1_test/change_availability_test.go b/ocpp2.0.1_test/change_availability_test.go index b4422204..aac4830d 100644 --- a/ocpp2.0.1_test/change_availability_test.go +++ b/ocpp2.0.1_test/change_availability_test.go @@ -3,16 +3,13 @@ package ocpp2_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/availability" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/availability" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" ) func (suite *OcppV2TestSuite) TestChangeAvailabilityRequestValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {availability.ChangeAvailabilityRequest{OperationalStatus: availability.OperationalStatusOperative, Evse: &types.EVSE{ID: 1, ConnectorID: newInt(1)}}, true}, {availability.ChangeAvailabilityRequest{OperationalStatus: availability.OperationalStatusInoperative, Evse: &types.EVSE{ID: 1}}, true}, @@ -22,11 +19,10 @@ func (suite *OcppV2TestSuite) TestChangeAvailabilityRequestValidation() { {availability.ChangeAvailabilityRequest{OperationalStatus: "invalidAvailabilityType"}, false}, {availability.ChangeAvailabilityRequest{OperationalStatus: availability.OperationalStatusOperative, Evse: &types.EVSE{ID: -1}}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestChangeAvailabilityConfirmationValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {availability.ChangeAvailabilityResponse{Status: availability.ChangeAvailabilityStatusAccepted}, true}, {availability.ChangeAvailabilityResponse{Status: availability.ChangeAvailabilityStatusRejected}, true}, @@ -34,12 +30,11 @@ func (suite *OcppV2TestSuite) TestChangeAvailabilityConfirmationValidation() { {availability.ChangeAvailabilityResponse{Status: "invalidAvailabilityStatus"}, false}, {availability.ChangeAvailabilityResponse{}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } // Test func (suite *OcppV2TestSuite) TestChangeAvailabilityE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -55,30 +50,30 @@ func (suite *OcppV2TestSuite) TestChangeAvailabilityE2EMocked() { handler := &MockChargingStationAvailabilityHandler{} handler.On("OnChangeAvailability", mock.Anything).Return(changeAvailabilityConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*availability.ChangeAvailabilityRequest) - require.True(t, ok) - require.NotNil(t, request.Evse) - assert.Equal(t, evse.ID, request.Evse.ID) - assert.Equal(t, *evse.ConnectorID, *request.Evse.ConnectorID) - assert.Equal(t, operationalStatus, request.OperationalStatus) + suite.Require().True(ok) + suite.Require().NotNil(request.Evse) + suite.Equal(evse.ID, request.Evse.ID) + suite.Equal(*evse.ConnectorID, *request.Evse.ConnectorID) + suite.Equal(operationalStatus, request.OperationalStatus) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.ChangeAvailability(wsId, func(confirmation *availability.ChangeAvailabilityResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, operationalStatus, func(req *availability.ChangeAvailabilityRequest) { req.Evse = &evse }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestChangeAvailabilityInvalidEndpoint() { diff --git a/ocpp2.0.1_test/clear_cache_test.go b/ocpp2.0.1_test/clear_cache_test.go index 2b827193..8866fa10 100644 --- a/ocpp2.0.1_test/clear_cache_test.go +++ b/ocpp2.0.1_test/clear_cache_test.go @@ -3,25 +3,21 @@ package ocpp2_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/authorization" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/authorization" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" ) // Test func (suite *OcppV2TestSuite) TestClearCacheRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {authorization.ClearCacheRequest{}, true}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestClearCacheConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {authorization.ClearCacheResponse{Status: authorization.ClearCacheStatusAccepted, StatusInfo: types.NewStatusInfo("200", "ok")}, true}, {authorization.ClearCacheResponse{Status: authorization.ClearCacheStatusAccepted}, true}, @@ -29,11 +25,10 @@ func (suite *OcppV2TestSuite) TestClearCacheConfirmationValidation() { {authorization.ClearCacheResponse{Status: "invalidClearCacheStatus"}, false}, {authorization.ClearCacheResponse{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestClearCacheE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -52,17 +47,17 @@ func (suite *OcppV2TestSuite) TestClearCacheE2EMocked() { // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.ClearCache(wsId, func(confirmation *authorization.ClearCacheResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestClearCacheInvalidEndpoint() { diff --git a/ocpp2.0.1_test/clear_charging_profile_test.go b/ocpp2.0.1_test/clear_charging_profile_test.go index 0ea450ea..521213fe 100644 --- a/ocpp2.0.1_test/clear_charging_profile_test.go +++ b/ocpp2.0.1_test/clear_charging_profile_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestClearChargingProfileRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {smartcharging.ClearChargingProfileRequest{ChargingProfileID: newInt(1), ChargingProfileCriteria: &smartcharging.ClearChargingProfileType{EvseID: newInt(1), ChargingProfilePurpose: types.ChargingProfilePurposeChargingStationMaxProfile, StackLevel: newInt(1)}}, true}, {smartcharging.ClearChargingProfileRequest{ChargingProfileID: newInt(1), ChargingProfileCriteria: &smartcharging.ClearChargingProfileType{EvseID: newInt(1), ChargingProfilePurpose: types.ChargingProfilePurposeChargingStationMaxProfile}}, true}, @@ -25,11 +22,10 @@ func (suite *OcppV2TestSuite) TestClearChargingProfileRequestValidation() { {smartcharging.ClearChargingProfileRequest{ChargingProfileCriteria: &smartcharging.ClearChargingProfileType{ChargingProfilePurpose: "invalidChargingProfilePurposeType"}}, false}, {smartcharging.ClearChargingProfileRequest{ChargingProfileCriteria: &smartcharging.ClearChargingProfileType{StackLevel: newInt(-1)}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestClearChargingProfileConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {smartcharging.ClearChargingProfileResponse{Status: smartcharging.ClearChargingProfileStatusAccepted, StatusInfo: types.NewStatusInfo("200", "ok")}, true}, {smartcharging.ClearChargingProfileResponse{Status: smartcharging.ClearChargingProfileStatusAccepted}, true}, @@ -37,11 +33,10 @@ func (suite *OcppV2TestSuite) TestClearChargingProfileConfirmationValidation() { {smartcharging.ClearChargingProfileResponse{}, false}, {smartcharging.ClearChargingProfileResponse{StatusInfo: types.NewStatusInfo("", "")}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestClearChargingProfileE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -61,32 +56,32 @@ func (suite *OcppV2TestSuite) TestClearChargingProfileE2EMocked() { handler := &MockChargingStationSmartChargingHandler{} handler.On("OnClearChargingProfile", mock.Anything).Return(clearChargingProfileConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*smartcharging.ClearChargingProfileRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, *chargingProfileId, *request.ChargingProfileID) - assert.Equal(t, *chargingProfileCriteria.EvseID, *request.ChargingProfileCriteria.EvseID) - assert.Equal(t, chargingProfileCriteria.ChargingProfilePurpose, request.ChargingProfileCriteria.ChargingProfilePurpose) - assert.Equal(t, *chargingProfileCriteria.StackLevel, *request.ChargingProfileCriteria.StackLevel) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(*chargingProfileId, *request.ChargingProfileID) + suite.Equal(*chargingProfileCriteria.EvseID, *request.ChargingProfileCriteria.EvseID) + suite.Equal(chargingProfileCriteria.ChargingProfilePurpose, request.ChargingProfileCriteria.ChargingProfilePurpose) + suite.Equal(*chargingProfileCriteria.StackLevel, *request.ChargingProfileCriteria.StackLevel) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.ClearChargingProfile(wsId, func(confirmation *smartcharging.ClearChargingProfileResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, func(request *smartcharging.ClearChargingProfileRequest) { request.ChargingProfileID = chargingProfileId request.ChargingProfileCriteria = &chargingProfileCriteria }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestClearChargingProfileInvalidEndpoint() { diff --git a/ocpp2.0.1_test/clear_display_message_test.go b/ocpp2.0.1_test/clear_display_message_test.go index 1d0ca826..6afa790c 100644 --- a/ocpp2.0.1_test/clear_display_message_test.go +++ b/ocpp2.0.1_test/clear_display_message_test.go @@ -3,36 +3,31 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/display" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/display" ) // Test func (suite *OcppV2TestSuite) TestClearDisplayMessageRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {display.ClearDisplayRequest{ID: 42}, true}, {display.ClearDisplayRequest{}, true}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestClearDisplayMessageResponseValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {display.ClearDisplayResponse{Status: display.ClearMessageStatusAccepted}, true}, {display.ClearDisplayResponse{Status: display.ClearMessageStatusUnknown}, true}, {display.ClearDisplayResponse{Status: "invalidClearMessageStatus"}, false}, {display.ClearDisplayResponse{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestClearDisplayMessageE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -46,26 +41,26 @@ func (suite *OcppV2TestSuite) TestClearDisplayMessageE2EMocked() { handler := &MockChargingStationDisplayHandler{} handler.On("OnClearDisplay", mock.Anything).Return(clearDisplayConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*display.ClearDisplayRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, displayMessageId, request.ID) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(displayMessageId, request.ID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.ClearDisplay(wsId, func(confirmation *display.ClearDisplayResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, displayMessageId) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestClearDisplayMessageInvalidEndpoint() { diff --git a/ocpp2.0.1_test/clear_variable_monitoring_test.go b/ocpp2.0.1_test/clear_variable_monitoring_test.go index 39489b05..6e927eca 100644 --- a/ocpp2.0.1_test/clear_variable_monitoring_test.go +++ b/ocpp2.0.1_test/clear_variable_monitoring_test.go @@ -3,16 +3,13 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" ) // Test func (suite *OcppV2TestSuite) TestClearVariableMonitoringRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {diagnostics.ClearVariableMonitoringRequest{ID: []int{0, 2, 15}}, true}, {diagnostics.ClearVariableMonitoringRequest{ID: []int{0}}, true}, @@ -20,11 +17,10 @@ func (suite *OcppV2TestSuite) TestClearVariableMonitoringRequestValidation() { {diagnostics.ClearVariableMonitoringRequest{}, false}, {diagnostics.ClearVariableMonitoringRequest{ID: []int{-1}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestClearVariableMonitoringConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {diagnostics.ClearVariableMonitoringResponse{ClearMonitoringResult: []diagnostics.ClearMonitoringResult{{ID: 2, Status: diagnostics.ClearMonitoringStatusAccepted}}}, true}, {diagnostics.ClearVariableMonitoringResponse{ClearMonitoringResult: []diagnostics.ClearMonitoringResult{{ID: 2}}}, false}, @@ -33,11 +29,10 @@ func (suite *OcppV2TestSuite) TestClearVariableMonitoringConfirmationValidation( {diagnostics.ClearVariableMonitoringResponse{ClearMonitoringResult: []diagnostics.ClearMonitoringResult{{ID: -1, Status: diagnostics.ClearMonitoringStatusAccepted}}}, false}, {diagnostics.ClearVariableMonitoringResponse{ClearMonitoringResult: []diagnostics.ClearMonitoringResult{{ID: 2, Status: "invalidClearMonitoringStatus"}}}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestClearVariableMonitoringE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -52,32 +47,32 @@ func (suite *OcppV2TestSuite) TestClearVariableMonitoringE2EMocked() { handler := &MockChargingStationDiagnosticsHandler{} handler.On("OnClearVariableMonitoring", mock.Anything).Return(clearVariableMonitoringConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*diagnostics.ClearVariableMonitoringRequest) - require.True(t, ok) - require.NotNil(t, request) - require.Len(t, request.ID, 2) - assert.Equal(t, ids[0], request.ID[0]) - assert.Equal(t, ids[1], request.ID[1]) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Require().Len(request.ID, 2) + suite.Equal(ids[0], request.ID[0]) + suite.Equal(ids[1], request.ID[1]) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.ClearVariableMonitoring(wsId, func(confirmation *diagnostics.ClearVariableMonitoringResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - require.Len(t, confirmation.ClearMonitoringResult, 2) - assert.Equal(t, result1.ID, confirmation.ClearMonitoringResult[0].ID) - assert.Equal(t, result1.Status, confirmation.ClearMonitoringResult[0].Status) - assert.Equal(t, result2.ID, confirmation.ClearMonitoringResult[1].ID) - assert.Equal(t, result2.Status, confirmation.ClearMonitoringResult[1].Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Require().Len(confirmation.ClearMonitoringResult, 2) + suite.Equal(result1.ID, confirmation.ClearMonitoringResult[0].ID) + suite.Equal(result1.Status, confirmation.ClearMonitoringResult[0].Status) + suite.Equal(result2.ID, confirmation.ClearMonitoringResult[1].ID) + suite.Equal(result2.Status, confirmation.ClearMonitoringResult[1].Status) resultChannel <- true }, ids) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestClearVariableMonitoringInvalidEndpoint() { diff --git a/ocpp2.0.1_test/cleared_charging_limit_test.go b/ocpp2.0.1_test/cleared_charging_limit_test.go index c3fbbeaf..92fd2151 100644 --- a/ocpp2.0.1_test/cleared_charging_limit_test.go +++ b/ocpp2.0.1_test/cleared_charging_limit_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Tests func (suite *OcppV2TestSuite) TestClearedChargingLimitRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {smartcharging.ClearedChargingLimitRequest{ChargingLimitSource: types.ChargingLimitSourceEMS, EvseID: newInt(0)}, true}, {smartcharging.ClearedChargingLimitRequest{ChargingLimitSource: types.ChargingLimitSourceEMS}, true}, @@ -21,19 +18,17 @@ func (suite *OcppV2TestSuite) TestClearedChargingLimitRequestValidation() { {smartcharging.ClearedChargingLimitRequest{ChargingLimitSource: types.ChargingLimitSourceEMS, EvseID: newInt(-1)}, false}, {smartcharging.ClearedChargingLimitRequest{ChargingLimitSource: "invalidChargingLimitSource"}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestClearedChargingLimitConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {smartcharging.ClearedChargingLimitResponse{}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestClearedChargingLimitE2EMocked() { - t := suite.T() wsId := "test_id" messageId := "1234" wsUrl := "someUrl" @@ -47,22 +42,22 @@ func (suite *OcppV2TestSuite) TestClearedChargingLimitE2EMocked() { handler := &MockCSMSSmartChargingHandler{} handler.On("OnClearedChargingLimit", mock.AnythingOfType("string"), mock.Anything).Return(clearedChargingLimitConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*smartcharging.ClearedChargingLimitRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, chargingLimitSource, request.ChargingLimitSource) - assert.Equal(t, evseID, *request.EvseID) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(chargingLimitSource, request.ChargingLimitSource) + suite.Equal(evseID, *request.EvseID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) confirmation, err := suite.chargingStation.ClearedChargingLimit(chargingLimitSource, func(request *smartcharging.ClearedChargingLimitRequest) { request.EvseID = newInt(evseID) }) - require.Nil(t, err) - require.NotNil(t, confirmation) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) } func (suite *OcppV2TestSuite) TestClearedChargingLimitInvalidEndpoint() { diff --git a/ocpp2.0.1_test/common_test.go b/ocpp2.0.1_test/common_test.go index d3adf79f..972d0fc9 100644 --- a/ocpp2.0.1_test/common_test.go +++ b/ocpp2.0.1_test/common_test.go @@ -7,8 +7,8 @@ import ( "github.com/relvacode/iso8601" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/display" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/display" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Utility functions @@ -62,11 +62,10 @@ func (suite *OcppV2TestSuite) TestIdTokenInfoValidation() { {types.IdTokenInfo{Status: types.AuthorizationStatusAccepted, CacheExpiryDateTime: types.NewDateTime(time.Now()), ChargingPriority: 10}, false}, {types.IdTokenInfo{Status: "invalidAuthStatus"}, false}, } - ExecuteGenericTestTable(suite.T(), testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestStatusInfo() { - t := suite.T() var testTable = []GenericTestEntry{ {types.StatusInfo{ReasonCode: "okCode", AdditionalInfo: "someAdditionalInfo"}, true}, {types.StatusInfo{ReasonCode: "okCode", AdditionalInfo: ""}, true}, @@ -76,11 +75,10 @@ func (suite *OcppV2TestSuite) TestStatusInfo() { {types.StatusInfo{ReasonCode: ">20.................."}, false}, {types.StatusInfo{ReasonCode: "okCode", AdditionalInfo: ">512............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................."}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestChargingSchedulePeriodValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {types.ChargingSchedulePeriod{StartPeriod: 0, Limit: 10.0, NumberPhases: newInt(3)}, true}, {types.ChargingSchedulePeriod{StartPeriod: 0, Limit: 10.0}, true}, @@ -90,11 +88,10 @@ func (suite *OcppV2TestSuite) TestChargingSchedulePeriodValidation() { {types.ChargingSchedulePeriod{StartPeriod: -1, Limit: 10.0}, false}, {types.ChargingSchedulePeriod{StartPeriod: 0, Limit: 10.0, NumberPhases: newInt(-1)}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestChargingScheduleValidation() { - t := suite.T() chargingSchedulePeriods := make([]types.ChargingSchedulePeriod, 2) chargingSchedulePeriods[0] = types.NewChargingSchedulePeriod(0, 10.0) chargingSchedulePeriods[1] = types.NewChargingSchedulePeriod(100, 8.0) @@ -109,11 +106,10 @@ func (suite *OcppV2TestSuite) TestChargingScheduleValidation() { {types.ChargingSchedule{Duration: newInt(0), StartSchedule: types.NewDateTime(time.Now()), ChargingRateUnit: types.ChargingRateUnitWatts, ChargingSchedulePeriod: make([]types.ChargingSchedulePeriod, 0), MinChargingRate: newFloat(1.0)}, false}, {types.ChargingSchedule{Duration: newInt(-1), StartSchedule: types.NewDateTime(time.Now()), ChargingRateUnit: "invalidChargeRateUnit", ChargingSchedulePeriod: chargingSchedulePeriods, MinChargingRate: newFloat(1.0)}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestComponentVariableValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {types.ComponentVariable{Component: types.Component{Name: "component1", Instance: "instance1", EVSE: &types.EVSE{ID: 2, ConnectorID: newInt(2)}}, Variable: types.Variable{Name: "variable1", Instance: "instance1"}}, true}, {types.ComponentVariable{Component: types.Component{Name: "component1", Instance: "instance1", EVSE: &types.EVSE{ID: 2}}, Variable: types.Variable{Name: "variable1", Instance: "instance1"}}, true}, @@ -132,7 +128,7 @@ func (suite *OcppV2TestSuite) TestComponentVariableValidation() { {types.ComponentVariable{Component: types.Component{Name: "component1", Instance: "instance1", EVSE: &types.EVSE{ID: 2, ConnectorID: newInt(-2)}}, Variable: types.Variable{Name: "variable1", Instance: "instance1"}}, false}, {types.ComponentVariable{Component: types.Component{Name: "component1", Instance: "instance1", EVSE: &types.EVSE{ID: -2, ConnectorID: newInt(2)}}, Variable: types.Variable{Name: "variable1", Instance: "instance1"}}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestConsumptionCostValidation() { @@ -149,7 +145,7 @@ func (suite *OcppV2TestSuite) TestConsumptionCostValidation() { {types.NewConsumptionCost(1.0, []types.CostType{{CostKind: "invalidCostKind", Amount: 7, AmountMultiplier: newInt(3)}}), false}, {types.NewConsumptionCost(1.0, []types.CostType{{CostKind: types.CostKindRelativePricePercentage, Amount: 7}, {CostKind: types.CostKindRelativePricePercentage, Amount: 7}, {CostKind: types.CostKindRelativePricePercentage, Amount: 7}, {CostKind: types.CostKindRelativePricePercentage, Amount: 7}}), false}, } - ExecuteGenericTestTable(suite.T(), testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestSalesTariffEntryValidation() { @@ -165,7 +161,7 @@ func (suite *OcppV2TestSuite) TestSalesTariffEntryValidation() { {types.SalesTariffEntry{EPriceLevel: newInt(8), RelativeTimeInterval: types.RelativeTimeInterval{Start: 500, Duration: newInt(1200)}, ConsumptionCost: []types.ConsumptionCost{dummyCostType, dummyCostType, dummyCostType, dummyCostType}}, false}, {types.SalesTariffEntry{EPriceLevel: newInt(8), RelativeTimeInterval: types.RelativeTimeInterval{Start: 500, Duration: newInt(1200)}, ConsumptionCost: []types.ConsumptionCost{types.NewConsumptionCost(1.0, []types.CostType{{}})}}, false}, } - ExecuteGenericTestTable(suite.T(), testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestSalesTariffValidation() { @@ -180,11 +176,10 @@ func (suite *OcppV2TestSuite) TestSalesTariffValidation() { {types.SalesTariff{ID: 1, SalesTariffDescription: ">32..............................", NumEPriceLevels: newInt(1), SalesTariffEntry: []types.SalesTariffEntry{dummySalesTariffEntry}}, false}, {types.SalesTariff{ID: 1, SalesTariffDescription: "someDesc", NumEPriceLevels: newInt(1), SalesTariffEntry: []types.SalesTariffEntry{{EPriceLevel: newInt(-1)}}}, false}, } - ExecuteGenericTestTable(suite.T(), testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestChargingProfileValidation() { - t := suite.T() chargingSchedule := types.NewChargingSchedule(1, types.ChargingRateUnitWatts, types.NewChargingSchedulePeriod(0, 10.0), types.NewChargingSchedulePeriod(100, 8.0)) var testTable = []GenericTestEntry{ {types.ChargingProfile{ID: 1, StackLevel: 1, ChargingProfilePurpose: types.ChargingProfilePurposeChargingStationMaxProfile, ChargingProfileKind: types.ChargingProfileKindAbsolute, RecurrencyKind: types.RecurrencyKindDaily, ValidFrom: types.NewDateTime(time.Now()), ValidTo: types.NewDateTime(time.Now().Add(8 * time.Hour)), TransactionID: "d34d", ChargingSchedule: []types.ChargingSchedule{*chargingSchedule}}, true}, @@ -203,11 +198,10 @@ func (suite *OcppV2TestSuite) TestChargingProfileValidation() { {types.ChargingProfile{ID: 1, StackLevel: 1, ChargingProfilePurpose: types.ChargingProfilePurposeChargingStationMaxProfile, ChargingProfileKind: types.ChargingProfileKindAbsolute, ChargingSchedule: []types.ChargingSchedule{*types.NewChargingSchedule(1, types.ChargingRateUnitWatts)}}, false}, {types.ChargingProfile{ID: 1, StackLevel: 1, ChargingProfilePurpose: types.ChargingProfilePurposeChargingStationMaxProfile, ChargingProfileKind: types.ChargingProfileKindAbsolute, ChargingSchedule: []types.ChargingSchedule{*chargingSchedule, *chargingSchedule, *chargingSchedule, *chargingSchedule}}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestSignedMeterValue() { - t := suite.T() var testTable = []GenericTestEntry{ {types.SignedMeterValue{SignedMeterData: "0xdeadbeef", SigningMethod: "ECDSAP256SHA256", EncodingMethod: "DLMS Message", PublicKey: "0xd34dc0de"}, true}, {types.SignedMeterValue{SignedMeterData: "0xdeadbeef", SigningMethod: "ECDSAP256SHA256", EncodingMethod: "DLMS Message"}, false}, @@ -219,11 +213,10 @@ func (suite *OcppV2TestSuite) TestSignedMeterValue() { {types.SignedMeterValue{SignedMeterData: "0xdeadbeef", SigningMethod: "ECDSAP256SHA256", EncodingMethod: ">50................................................", PublicKey: "0xd34dc0de"}, false}, {types.SignedMeterValue{SignedMeterData: "0xdeadbeef", SigningMethod: "ECDSAP256SHA256", EncodingMethod: "DLMS Message", PublicKey: ">2500................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................"}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestSampledValueValidation() { - t := suite.T() signedMeterValue := types.SignedMeterValue{ SignedMeterData: "0xdeadbeef", SigningMethod: "ECDSAP256SHA256", @@ -248,7 +241,7 @@ func (suite *OcppV2TestSuite) TestSampledValueValidation() { {types.SampledValue{Value: 3.14, SignedMeterValue: &types.SignedMeterValue{}}, false}, {types.SampledValue{Value: 3.14, UnitOfMeasure: &types.UnitOfMeasure{Unit: "invalidUnit>20......."}}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestMeterValueValidation() { @@ -259,7 +252,7 @@ func (suite *OcppV2TestSuite) TestMeterValueValidation() { {types.MeterValue{}, false}, {types.MeterValue{Timestamp: types.DateTime{Time: time.Now()}, SampledValue: []types.SampledValue{{Value: 3.14, Context: "invalidContext", Measurand: types.MeasurandPowerActiveExport, Phase: types.PhaseL2, Location: types.LocationBody}}}, false}, } - ExecuteGenericTestTable(suite.T(), testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestMessageInfoValidation() { @@ -279,7 +272,7 @@ func (suite *OcppV2TestSuite) TestMessageInfoValidation() { {display.MessageInfo{ID: 42, Priority: display.MessagePriorityAlwaysFront, State: display.MessageStateIdle, TransactionID: ">36..................................", Message: types.MessageContent{Format: types.MessageFormatUTF8, Content: "hello world"}}, false}, {display.MessageInfo{ID: 42, Priority: display.MessagePriorityAlwaysFront, State: display.MessageStateIdle, StartDateTime: types.NewDateTime(time.Now()), EndDateTime: types.NewDateTime(time.Now().Add(1 * time.Hour)), TransactionID: "123456", Message: types.MessageContent{Format: types.MessageFormatUTF8, Content: "hello world"}, Display: &types.Component{}}, false}, } - ExecuteGenericTestTable(suite.T(), testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestUnmarshalDateTime() { diff --git a/ocpp2.0.1_test/cost_updated_test.go b/ocpp2.0.1_test/cost_updated_test.go index da837fd8..863a8305 100644 --- a/ocpp2.0.1_test/cost_updated_test.go +++ b/ocpp2.0.1_test/cost_updated_test.go @@ -3,16 +3,13 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/tariffcost" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/tariffcost" ) // Test func (suite *OcppV2TestSuite) TestCostUpdatedRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {tariffcost.CostUpdatedRequest{TotalCost: 24.6, TransactionID: "1234"}, true}, {tariffcost.CostUpdatedRequest{TotalCost: 24.6}, false}, @@ -20,19 +17,17 @@ func (suite *OcppV2TestSuite) TestCostUpdatedRequestValidation() { {tariffcost.CostUpdatedRequest{}, false}, {tariffcost.CostUpdatedRequest{TotalCost: 24.6, TransactionID: ">36.................................."}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestCostUpdatedConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {tariffcost.CostUpdatedResponse{}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestCostUpdatedE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -46,26 +41,26 @@ func (suite *OcppV2TestSuite) TestCostUpdatedE2EMocked() { handler := &MockChargingStationTariffCostHandler{} handler.On("OnCostUpdated", mock.Anything).Return(costUpdatedConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*tariffcost.CostUpdatedRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, totalCost, request.TotalCost) - assert.Equal(t, transactionId, request.TransactionID) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(totalCost, request.TotalCost) + suite.Equal(transactionId, request.TransactionID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.CostUpdated(wsId, func(confirmation *tariffcost.CostUpdatedResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) resultChannel <- true }, totalCost, transactionId) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestCostUpdatedInvalidEndpoint() { diff --git a/ocpp2.0.1_test/customer_information_test.go b/ocpp2.0.1_test/customer_information_test.go index 21776090..fd411143 100644 --- a/ocpp2.0.1_test/customer_information_test.go +++ b/ocpp2.0.1_test/customer_information_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestCustomerInformationRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {diagnostics.CustomerInformationRequest{RequestID: 42, Report: true, Clear: true, CustomerIdentifier: "0001", IdToken: &types.IdToken{IdToken: "1234", Type: types.IdTokenTypeKeyCode, AdditionalInfo: nil}, CustomerCertificate: &types.CertificateHashData{HashAlgorithm: types.SHA256, IssuerNameHash: "hash00", IssuerKeyHash: "hash01", SerialNumber: "serial0"}}, true}, {diagnostics.CustomerInformationRequest{RequestID: 42, Report: true, Clear: true, CustomerIdentifier: "0001", IdToken: &types.IdToken{IdToken: "1234", Type: types.IdTokenTypeKeyCode, AdditionalInfo: nil}}, true}, @@ -28,21 +25,19 @@ func (suite *OcppV2TestSuite) TestCustomerInformationRequestValidation() { {diagnostics.CustomerInformationRequest{RequestID: 42, Report: true, Clear: true, IdToken: &types.IdToken{IdToken: "1234", Type: "invalidTokenType", AdditionalInfo: nil}}, false}, {diagnostics.CustomerInformationRequest{RequestID: 42, Report: true, Clear: true, CustomerCertificate: &types.CertificateHashData{HashAlgorithm: "invalidHasAlgorithm", IssuerNameHash: "hash00", IssuerKeyHash: "hash01", SerialNumber: "serial0"}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestCustomerInformationConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {diagnostics.CustomerInformationResponse{Status: diagnostics.CustomerInformationStatusAccepted}, true}, {diagnostics.CustomerInformationResponse{}, false}, {diagnostics.CustomerInformationResponse{Status: "invalidCustomerInformationStatus"}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestCustomerInformationE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -62,35 +57,35 @@ func (suite *OcppV2TestSuite) TestCustomerInformationE2EMocked() { handler := &MockChargingStationDiagnosticsHandler{} handler.On("OnCustomerInformation", mock.Anything).Return(customerInformationConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*diagnostics.CustomerInformationRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, requestId, request.RequestID) - assert.Equal(t, report, request.Report) - assert.Equal(t, clear, request.Clear) - assert.Equal(t, customerId, request.CustomerIdentifier) - require.NotNil(t, request.IdToken) - require.NotNil(t, request.CustomerCertificate) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(requestId, request.RequestID) + suite.Equal(report, request.Report) + suite.Equal(clear, request.Clear) + suite.Equal(customerId, request.CustomerIdentifier) + suite.Require().NotNil(request.IdToken) + suite.Require().NotNil(request.CustomerCertificate) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.CustomerInformation(wsId, func(confirmation *diagnostics.CustomerInformationResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - require.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Require().Equal(status, confirmation.Status) resultChannel <- true }, requestId, report, clear, func(request *diagnostics.CustomerInformationRequest) { request.CustomerIdentifier = customerId request.IdToken = &idToken request.CustomerCertificate = &customerCertificate }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestCustomerInformationInvalidEndpoint() { diff --git a/ocpp2.0.1_test/data_transfer_test.go b/ocpp2.0.1_test/data_transfer_test.go index 7b4782fa..9d6c478f 100644 --- a/ocpp2.0.1_test/data_transfer_test.go +++ b/ocpp2.0.1_test/data_transfer_test.go @@ -3,16 +3,13 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/data" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/data" ) // Test func (suite *OcppV2TestSuite) TestDataTransferRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {data.DataTransferRequest{VendorID: "12345"}, true}, {data.DataTransferRequest{VendorID: "12345", MessageID: "6789"}, true}, @@ -21,11 +18,10 @@ func (suite *OcppV2TestSuite) TestDataTransferRequestValidation() { {data.DataTransferRequest{VendorID: ">255............................................................................................................................................................................................................................................................"}, false}, {data.DataTransferRequest{VendorID: "12345", MessageID: ">50................................................"}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestDataTransferConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {data.DataTransferResponse{Status: data.DataTransferStatusAccepted}, true}, {data.DataTransferResponse{Status: data.DataTransferStatusRejected}, true}, @@ -34,11 +30,10 @@ func (suite *OcppV2TestSuite) TestDataTransferConfirmationValidation() { {data.DataTransferResponse{Status: "invalidDataTransferStatus"}, false}, {data.DataTransferResponse{Status: data.DataTransferStatusAccepted, Data: "mockData"}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestDataTransferFromChargePointE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -52,24 +47,23 @@ func (suite *OcppV2TestSuite) TestDataTransferFromChargePointE2EMocked() { handler := &MockCSMSDataHandler{} handler.On("OnDataTransfer", mock.AnythingOfType("string"), mock.Anything).Return(dataTransferConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*data.DataTransferRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, vendorId, request.VendorID) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(vendorId, request.VendorID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - assert.Nil(t, err) + suite.Nil(err) confirmation, err := suite.chargingStation.DataTransfer(vendorId) - assert.Nil(t, err) - assert.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Nil(err) + suite.NotNil(confirmation) + suite.Equal(status, confirmation.Status) } func (suite *OcppV2TestSuite) TestDataTransferFromCentralSystemE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -83,24 +77,24 @@ func (suite *OcppV2TestSuite) TestDataTransferFromCentralSystemE2EMocked() { handler := &MockChargingStationDataHandler{} handler.On("OnDataTransfer", mock.Anything).Return(dataTransferConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*data.DataTransferRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, vendorId, request.VendorID) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(vendorId, request.VendorID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - assert.Nil(t, err) + suite.Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.DataTransfer(wsId, func(confirmation *data.DataTransferResponse, err error) { - assert.Nil(t, err) - assert.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Nil(err) + suite.NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, vendorId) - assert.Nil(t, err) + suite.Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } diff --git a/ocpp2.0.1_test/delete_certificate_test.go b/ocpp2.0.1_test/delete_certificate_test.go index 641be98e..86941d6c 100644 --- a/ocpp2.0.1_test/delete_certificate_test.go +++ b/ocpp2.0.1_test/delete_certificate_test.go @@ -3,27 +3,23 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/iso15118" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/iso15118" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestDeleteCertificateRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {iso15118.DeleteCertificateRequest{CertificateHashData: types.CertificateHashData{HashAlgorithm: types.SHA256, IssuerNameHash: "hash00", IssuerKeyHash: "hash01", SerialNumber: "serial0"}}, true}, {iso15118.DeleteCertificateRequest{}, false}, {iso15118.DeleteCertificateRequest{CertificateHashData: types.CertificateHashData{HashAlgorithm: "invalidHashAlgorithm", IssuerNameHash: "hash00", IssuerKeyHash: "hash01", SerialNumber: "serial0"}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestDeleteCertificateConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {iso15118.DeleteCertificateResponse{Status: iso15118.DeleteCertificateStatusAccepted}, true}, {iso15118.DeleteCertificateResponse{Status: iso15118.DeleteCertificateStatusFailed}, true}, @@ -31,11 +27,10 @@ func (suite *OcppV2TestSuite) TestDeleteCertificateConfirmationValidation() { {iso15118.DeleteCertificateResponse{Status: "invalidDeleteCertificateStatus"}, false}, {iso15118.DeleteCertificateResponse{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestDeleteCertificateE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -50,29 +45,29 @@ func (suite *OcppV2TestSuite) TestDeleteCertificateE2EMocked() { handler := &MockChargingStationIso15118Handler{} handler.On("OnDeleteCertificate", mock.Anything).Return(deleteCertificateConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*iso15118.DeleteCertificateRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, certificateHashData.HashAlgorithm, request.CertificateHashData.HashAlgorithm) - assert.Equal(t, certificateHashData.IssuerNameHash, request.CertificateHashData.IssuerNameHash) - assert.Equal(t, certificateHashData.IssuerKeyHash, request.CertificateHashData.IssuerKeyHash) - assert.Equal(t, certificateHashData.SerialNumber, request.CertificateHashData.SerialNumber) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(certificateHashData.HashAlgorithm, request.CertificateHashData.HashAlgorithm) + suite.Equal(certificateHashData.IssuerNameHash, request.CertificateHashData.IssuerNameHash) + suite.Equal(certificateHashData.IssuerKeyHash, request.CertificateHashData.IssuerKeyHash) + suite.Equal(certificateHashData.SerialNumber, request.CertificateHashData.SerialNumber) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.DeleteCertificate(wsId, func(confirmation *iso15118.DeleteCertificateResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, certificateHashData) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestDeleteCertificateInvalidEndpoint() { diff --git a/ocpp2.0.1_test/firmware_status_notification_test.go b/ocpp2.0.1_test/firmware_status_notification_test.go index 9aa56f38..2544bb9b 100644 --- a/ocpp2.0.1_test/firmware_status_notification_test.go +++ b/ocpp2.0.1_test/firmware_status_notification_test.go @@ -3,16 +3,13 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/firmware" ) // Test func (suite *OcppV2TestSuite) TestFirmwareStatusNotificationRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {firmware.FirmwareStatusNotificationRequest{Status: firmware.FirmwareStatusDownloaded, RequestID: newInt(42)}, true}, {firmware.FirmwareStatusNotificationRequest{Status: firmware.FirmwareStatusDownloaded}, true}, @@ -21,19 +18,17 @@ func (suite *OcppV2TestSuite) TestFirmwareStatusNotificationRequestValidation() {firmware.FirmwareStatusNotificationRequest{Status: firmware.FirmwareStatusDownloaded, RequestID: newInt(-1)}, false}, {firmware.FirmwareStatusNotificationRequest{Status: "invalidFirmwareStatus"}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestFirmwareStatusNotificationConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {firmware.FirmwareStatusNotificationResponse{}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestFirmwareStatusNotificationE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -47,21 +42,21 @@ func (suite *OcppV2TestSuite) TestFirmwareStatusNotificationE2EMocked() { handler := &MockCSMSFirmwareHandler{} handler.On("OnFirmwareStatusNotification", mock.AnythingOfType("string"), mock.Anything).Return(firmwareStatusNotificationConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*firmware.FirmwareStatusNotificationRequest) - require.True(t, ok) - assert.Equal(t, status, request.Status) - assert.Equal(t, requestID, *request.RequestID) + suite.Require().True(ok) + suite.Equal(status, request.Status) + suite.Equal(requestID, *request.RequestID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) response, err := suite.chargingStation.FirmwareStatusNotification(status, func(request *firmware.FirmwareStatusNotificationRequest) { request.RequestID = &requestID }) - assert.Nil(t, err) - assert.NotNil(t, response) + suite.Nil(err) + suite.NotNil(response) } func (suite *OcppV2TestSuite) TestFirmwareStatusNotificationInvalidEndpoint() { diff --git a/ocpp2.0.1_test/get_15118ev_certificate_test.go b/ocpp2.0.1_test/get_15118ev_certificate_test.go index 65dd4fe4..4d782de4 100644 --- a/ocpp2.0.1_test/get_15118ev_certificate_test.go +++ b/ocpp2.0.1_test/get_15118ev_certificate_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/iso15118" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/iso15118" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestGet15118EVCertificateRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {iso15118.Get15118EVCertificateRequest{SchemaVersion: "1.0", Action: iso15118.CertificateActionInstall, ExiRequest: "deadbeef"}, true}, {iso15118.Get15118EVCertificateRequest{SchemaVersion: "1.0", Action: iso15118.CertificateActionUpdate, ExiRequest: "deadbeef"}, true}, @@ -24,11 +21,10 @@ func (suite *OcppV2TestSuite) TestGet15118EVCertificateRequestValidation() { {iso15118.Get15118EVCertificateRequest{SchemaVersion: "1.0", Action: "invalidCertificateAction", ExiRequest: "deadbeef"}, false}, {iso15118.Get15118EVCertificateRequest{SchemaVersion: "1.0", Action: iso15118.CertificateActionInstall, ExiRequest: newLongString(5601)}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestGet15118EVCertificateConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {iso15118.Get15118EVCertificateResponse{Status: types.Certificate15188EVStatusAccepted, ExiResponse: "deadbeef", StatusInfo: types.NewStatusInfo("200", "ok")}, true}, {iso15118.Get15118EVCertificateResponse{Status: types.Certificate15188EVStatusAccepted, ExiResponse: "deadbeef"}, true}, @@ -39,11 +35,10 @@ func (suite *OcppV2TestSuite) TestGet15118EVCertificateConfirmationValidation() {iso15118.Get15118EVCertificateResponse{Status: types.Certificate15188EVStatusAccepted, ExiResponse: newLongString(5601), StatusInfo: types.NewStatusInfo("200", "ok")}, false}, {iso15118.Get15118EVCertificateResponse{Status: types.Certificate15188EVStatusAccepted, ExiResponse: "deadbeef", StatusInfo: types.NewStatusInfo("", "")}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestGet15118EVCertificateE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -64,25 +59,25 @@ func (suite *OcppV2TestSuite) TestGet15118EVCertificateE2EMocked() { handler := &MockCSMSIso15118Handler{} handler.On("OnGet15118EVCertificate", mock.AnythingOfType("string"), mock.Anything).Return(get15118EVCertificateResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*iso15118.Get15118EVCertificateRequest) - require.True(t, ok) - assert.Equal(t, schemaVersion, request.SchemaVersion) - assert.Equal(t, action, request.Action) - assert.Equal(t, exiRequest, request.ExiRequest) + suite.Require().True(ok) + suite.Equal(schemaVersion, request.SchemaVersion) + suite.Equal(action, request.Action) + suite.Equal(exiRequest, request.ExiRequest) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) response, err := suite.chargingStation.Get15118EVCertificate(schemaVersion, action, exiRequest) - require.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, status, response.Status) - assert.Equal(t, exiResponse, response.ExiResponse) - require.NotNil(t, response.StatusInfo) - assert.Equal(t, statusInfo.ReasonCode, response.StatusInfo.ReasonCode) - assert.Equal(t, statusInfo.AdditionalInfo, response.StatusInfo.AdditionalInfo) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Equal(status, response.Status) + suite.Equal(exiResponse, response.ExiResponse) + suite.Require().NotNil(response.StatusInfo) + suite.Equal(statusInfo.ReasonCode, response.StatusInfo.ReasonCode) + suite.Equal(statusInfo.AdditionalInfo, response.StatusInfo.AdditionalInfo) } func (suite *OcppV2TestSuite) TestGet15118EVCertificateInvalidEndpoint() { diff --git a/ocpp2.0.1_test/get_base_report_test.go b/ocpp2.0.1_test/get_base_report_test.go index 3175b684..cbfc0ee0 100644 --- a/ocpp2.0.1_test/get_base_report_test.go +++ b/ocpp2.0.1_test/get_base_report_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestGetBaseReportRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {provisioning.GetBaseReportRequest{RequestID: 42, ReportBase: provisioning.ReportTypeConfigurationInventory}, true}, {provisioning.GetBaseReportRequest{ReportBase: provisioning.ReportTypeConfigurationInventory}, true}, @@ -21,21 +18,19 @@ func (suite *OcppV2TestSuite) TestGetBaseReportRequestValidation() { {provisioning.GetBaseReportRequest{}, false}, {provisioning.GetBaseReportRequest{RequestID: 42, ReportBase: "invalidReportType"}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestGetBaseReportConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {provisioning.GetBaseReportResponse{Status: types.GenericDeviceModelStatusAccepted}, true}, {provisioning.GetBaseReportResponse{Status: "invalidDeviceModelStatus"}, false}, {provisioning.GetBaseReportResponse{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestGetBaseReportE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -50,27 +45,27 @@ func (suite *OcppV2TestSuite) TestGetBaseReportE2EMocked() { handler := &MockChargingStationProvisioningHandler{} handler.On("OnGetBaseReport", mock.Anything).Return(getBaseReportConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*provisioning.GetBaseReportRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, requestID, request.RequestID) - assert.Equal(t, reportBase, request.ReportBase) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(requestID, request.RequestID) + suite.Equal(reportBase, request.ReportBase) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.GetBaseReport(wsId, func(confirmation *provisioning.GetBaseReportResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, requestID, reportBase) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestGetBaseReportInvalidEndpoint() { diff --git a/ocpp2.0.1_test/get_certificate_status_test.go b/ocpp2.0.1_test/get_certificate_status_test.go index a80ebe36..33eb8dad 100644 --- a/ocpp2.0.1_test/get_certificate_status_test.go +++ b/ocpp2.0.1_test/get_certificate_status_test.go @@ -3,27 +3,23 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/iso15118" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/iso15118" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestGetCertificateStatusRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {iso15118.GetCertificateStatusRequest{OcspRequestData: types.OCSPRequestDataType{HashAlgorithm: types.SHA256, IssuerNameHash: "hash00", IssuerKeyHash: "hash01", SerialNumber: "serial0", ResponderURL: "http://someUrl"}}, true}, {iso15118.GetCertificateStatusRequest{}, false}, {iso15118.GetCertificateStatusRequest{OcspRequestData: types.OCSPRequestDataType{HashAlgorithm: "invalidHashAlgorithm", IssuerNameHash: "hash00", IssuerKeyHash: "hash01", SerialNumber: "serial0", ResponderURL: "http://someUrl"}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestGetCertificateStatusConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {iso15118.GetCertificateStatusResponse{Status: types.GenericStatusAccepted, OcspResult: "deadbeef"}, true}, {iso15118.GetCertificateStatusResponse{Status: types.GenericStatusAccepted}, true}, @@ -32,11 +28,10 @@ func (suite *OcppV2TestSuite) TestGetCertificateStatusConfirmationValidation() { {iso15118.GetCertificateStatusResponse{Status: types.GenericStatusAccepted, OcspResult: newLongString(5501)}, false}, {iso15118.GetCertificateStatusResponse{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestGetCertificateStatusE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -53,25 +48,25 @@ func (suite *OcppV2TestSuite) TestGetCertificateStatusE2EMocked() { handler := &MockCSMSIso15118Handler{} handler.On("OnGetCertificateStatus", mock.AnythingOfType("string"), mock.Anything).Return(getCertificateStatusConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*iso15118.GetCertificateStatusRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, ocspData.HashAlgorithm, request.OcspRequestData.HashAlgorithm) - assert.Equal(t, ocspData.IssuerNameHash, request.OcspRequestData.IssuerNameHash) - assert.Equal(t, ocspData.IssuerKeyHash, request.OcspRequestData.IssuerKeyHash) - assert.Equal(t, ocspData.SerialNumber, request.OcspRequestData.SerialNumber) - assert.Equal(t, ocspData.ResponderURL, request.OcspRequestData.ResponderURL) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(ocspData.HashAlgorithm, request.OcspRequestData.HashAlgorithm) + suite.Equal(ocspData.IssuerNameHash, request.OcspRequestData.IssuerNameHash) + suite.Equal(ocspData.IssuerKeyHash, request.OcspRequestData.IssuerKeyHash) + suite.Equal(ocspData.SerialNumber, request.OcspRequestData.SerialNumber) + suite.Equal(ocspData.ResponderURL, request.OcspRequestData.ResponderURL) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) confirmation, err := suite.chargingStation.GetCertificateStatus(ocspData) - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) - assert.Equal(t, ocspResult, confirmation.OcspResult) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) + suite.Equal(ocspResult, confirmation.OcspResult) } func (suite *OcppV2TestSuite) TestGetCertificateStatusInvalidEndpoint() { diff --git a/ocpp2.0.1_test/get_charging_profiles_test.go b/ocpp2.0.1_test/get_charging_profiles_test.go index 637996cf..40bffd5b 100644 --- a/ocpp2.0.1_test/get_charging_profiles_test.go +++ b/ocpp2.0.1_test/get_charging_profiles_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestGetChargingProfilesRequestValidation() { - t := suite.T() validChargingProfileCriterion := smartcharging.ChargingProfileCriterion{ ChargingProfilePurpose: types.ChargingProfilePurposeTxDefaultProfile, StackLevel: newInt(2), @@ -33,22 +30,20 @@ func (suite *OcppV2TestSuite) TestGetChargingProfilesRequestValidation() { {smartcharging.GetChargingProfilesRequest{ChargingProfile: smartcharging.ChargingProfileCriterion{ChargingProfilePurpose: types.ChargingProfilePurposeTxDefaultProfile, StackLevel: newInt(2), ChargingProfileID: []int{1, 2}, ChargingLimitSource: []types.ChargingLimitSourceType{types.ChargingLimitSourceEMS, types.ChargingLimitSourceCSO, types.ChargingLimitSourceSO, types.ChargingLimitSourceOther, types.ChargingLimitSourceEMS}}}, false}, {smartcharging.GetChargingProfilesRequest{ChargingProfile: smartcharging.ChargingProfileCriterion{ChargingProfilePurpose: types.ChargingProfilePurposeTxDefaultProfile, StackLevel: newInt(2), ChargingProfileID: []int{1, 2}, ChargingLimitSource: []types.ChargingLimitSourceType{"invalidChargingLimitSource"}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestGetChargingProfilesConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {smartcharging.GetChargingProfilesResponse{Status: smartcharging.GetChargingProfileStatusAccepted}, true}, {smartcharging.GetChargingProfilesResponse{Status: smartcharging.GetChargingProfileStatusNoProfiles}, true}, {smartcharging.GetChargingProfilesResponse{Status: "invalidGetChargingProfilesStatus"}, false}, {smartcharging.GetChargingProfilesResponse{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestGetChargingProfilesE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -71,30 +66,30 @@ func (suite *OcppV2TestSuite) TestGetChargingProfilesE2EMocked() { handler.On("OnGetChargingProfiles", mock.Anything).Return(getChargingProfilesConfirmation, nil).Run(func(args mock.Arguments) { // Assert request message contents request, ok := args.Get(0).(*smartcharging.GetChargingProfilesRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, requestID, request.RequestID) - assert.Equal(t, evseID, *request.EvseID) - assert.Equal(t, chargingProfileCriterion.ChargingProfilePurpose, request.ChargingProfile.ChargingProfilePurpose) - assert.Equal(t, *chargingProfileCriterion.StackLevel, *request.ChargingProfile.StackLevel) - require.Len(t, request.ChargingProfile.ChargingProfileID, len(chargingProfileCriterion.ChargingProfileID)) - assert.Equal(t, chargingProfileCriterion.ChargingProfileID[0], request.ChargingProfile.ChargingProfileID[0]) - assert.Equal(t, chargingProfileCriterion.ChargingProfileID[1], request.ChargingProfile.ChargingProfileID[1]) - require.Len(t, request.ChargingProfile.ChargingLimitSource, len(chargingProfileCriterion.ChargingLimitSource)) - assert.Equal(t, chargingProfileCriterion.ChargingLimitSource[0], request.ChargingProfile.ChargingLimitSource[0]) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(requestID, request.RequestID) + suite.Equal(evseID, *request.EvseID) + suite.Equal(chargingProfileCriterion.ChargingProfilePurpose, request.ChargingProfile.ChargingProfilePurpose) + suite.Equal(*chargingProfileCriterion.StackLevel, *request.ChargingProfile.StackLevel) + suite.Require().Len(request.ChargingProfile.ChargingProfileID, len(chargingProfileCriterion.ChargingProfileID)) + suite.Equal(chargingProfileCriterion.ChargingProfileID[0], request.ChargingProfile.ChargingProfileID[0]) + suite.Equal(chargingProfileCriterion.ChargingProfileID[1], request.ChargingProfile.ChargingProfileID[1]) + suite.Require().Len(request.ChargingProfile.ChargingLimitSource, len(chargingProfileCriterion.ChargingLimitSource)) + suite.Equal(chargingProfileCriterion.ChargingLimitSource[0], request.ChargingProfile.ChargingLimitSource[0]) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.GetChargingProfiles(wsId, func(confirmation *smartcharging.GetChargingProfilesResponse, err error) { // Assert confirmation message contents - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, chargingProfileCriterion, @@ -102,9 +97,9 @@ func (suite *OcppV2TestSuite) TestGetChargingProfilesE2EMocked() { request.EvseID = &evseID request.RequestID = requestID }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestGetChargingProfilesInvalidEndpoint() { diff --git a/ocpp2.0.1_test/get_composite_schedule_test.go b/ocpp2.0.1_test/get_composite_schedule_test.go index 0aa27775..71ad4980 100644 --- a/ocpp2.0.1_test/get_composite_schedule_test.go +++ b/ocpp2.0.1_test/get_composite_schedule_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestGetCompositeScheduleRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {smartcharging.GetCompositeScheduleRequest{Duration: 600, EvseID: 1, ChargingRateUnit: types.ChargingRateUnitWatts}, true}, {smartcharging.GetCompositeScheduleRequest{Duration: 600, EvseID: 1}, true}, @@ -24,11 +21,10 @@ func (suite *OcppV2TestSuite) TestGetCompositeScheduleRequestValidation() { {smartcharging.GetCompositeScheduleRequest{Duration: -1, EvseID: 1, ChargingRateUnit: types.ChargingRateUnitWatts}, false}, {smartcharging.GetCompositeScheduleRequest{Duration: 600, EvseID: 1, ChargingRateUnit: "invalidChargingRateUnit"}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestGetCompositeScheduleConfirmationValidation() { - t := suite.T() chargingSchedule := types.NewChargingSchedule(1, types.ChargingRateUnitWatts, types.NewChargingSchedulePeriod(0, 10.0)) chargingSchedule.Duration = newInt(600) chargingSchedule.MinChargingRate = newFloat(6.0) @@ -47,11 +43,10 @@ func (suite *OcppV2TestSuite) TestGetCompositeScheduleConfirmationValidation() { {smartcharging.GetCompositeScheduleResponse{Status: smartcharging.GetCompositeScheduleStatusAccepted, StatusInfo: types.NewStatusInfo("invalidreasoncodeasitslongerthan20", "")}, false}, {smartcharging.GetCompositeScheduleResponse{Status: smartcharging.GetCompositeScheduleStatusAccepted, StatusInfo: types.NewStatusInfo("", ""), Schedule: &smartcharging.CompositeSchedule{StartDateTime: types.NewDateTime(time.Now()), ChargingSchedule: types.NewChargingSchedule(1, "invalidChargingRateUnit")}}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestGetCompositeScheduleE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -73,54 +68,55 @@ func (suite *OcppV2TestSuite) TestGetCompositeScheduleE2EMocked() { responseJson := fmt.Sprintf(`[3,"%v",{"status":"%v","statusInfo":{"reasonCode":"%v"},"schedule":{"startDateTime":"%v","chargingSchedule":{"id":%v,"startSchedule":"%v","duration":%v,"chargingRateUnit":"%v","minChargingRate":%v,"chargingSchedulePeriod":[{"startPeriod":%v,"limit":%v,"numberPhases":%v}]}}}]`, messageId, status, statusInfo.ReasonCode, compositeSchedule.StartDateTime.FormatTimestamp(), chargingSchedule.ID, chargingSchedule.StartSchedule.FormatTimestamp(), *chargingSchedule.Duration, chargingSchedule.ChargingRateUnit, *chargingSchedule.MinChargingRate, chargingSchedulePeriod.StartPeriod, chargingSchedulePeriod.Limit, *chargingSchedulePeriod.NumberPhases) getCompositeScheduleConfirmation := smartcharging.NewGetCompositeScheduleResponse(status) + getCompositeScheduleConfirmation.StatusInfo = statusInfo getCompositeScheduleConfirmation.Schedule = &compositeSchedule channel := NewMockWebSocket(wsId) handler := &MockChargingStationSmartChargingHandler{} handler.On("OnGetCompositeSchedule", mock.Anything).Return(getCompositeScheduleConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*smartcharging.GetCompositeScheduleRequest) - assert.True(t, ok) - assert.NotNil(t, request) - assert.Equal(t, duration, request.Duration) - assert.Equal(t, chargingRateUnit, request.ChargingRateUnit) - assert.Equal(t, evseID, request.EvseID) + suite.True(ok) + suite.NotNil(request) + suite.Equal(duration, request.Duration) + suite.Equal(chargingRateUnit, request.ChargingRateUnit) + suite.Equal(evseID, request.EvseID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - assert.Nil(t, err) + suite.Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.GetCompositeSchedule(wsId, func(confirmation *smartcharging.GetCompositeScheduleResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) - assert.Equal(t, statusInfo.ReasonCode, confirmation.StatusInfo.ReasonCode) - require.NotNil(t, confirmation.Schedule) - require.NotNil(t, confirmation.Schedule.StartDateTime) - assert.Equal(t, compositeSchedule.StartDateTime.FormatTimestamp(), confirmation.Schedule.StartDateTime.FormatTimestamp()) - require.NotNil(t, confirmation.Schedule.ChargingSchedule) - assert.Equal(t, chargingSchedule.ID, confirmation.Schedule.ChargingSchedule.ID) - assert.Equal(t, chargingSchedule.ChargingRateUnit, confirmation.Schedule.ChargingSchedule.ChargingRateUnit) - require.NotNil(t, confirmation.Schedule.ChargingSchedule.Duration) - assert.Equal(t, *chargingSchedule.Duration, *confirmation.Schedule.ChargingSchedule.Duration) - require.NotNil(t, confirmation.Schedule.ChargingSchedule.MinChargingRate) - assert.Equal(t, *chargingSchedule.MinChargingRate, *confirmation.Schedule.ChargingSchedule.MinChargingRate) - require.NotNil(t, confirmation.Schedule.ChargingSchedule.StartSchedule) - assert.Equal(t, chargingSchedule.StartSchedule.FormatTimestamp(), confirmation.Schedule.ChargingSchedule.StartSchedule.FormatTimestamp()) - require.Len(t, confirmation.Schedule.ChargingSchedule.ChargingSchedulePeriod, len(chargingSchedule.ChargingSchedulePeriod)) - assert.Equal(t, chargingSchedule.ChargingSchedulePeriod[0].Limit, confirmation.Schedule.ChargingSchedule.ChargingSchedulePeriod[0].Limit) - assert.Equal(t, chargingSchedule.ChargingSchedulePeriod[0].StartPeriod, confirmation.Schedule.ChargingSchedule.ChargingSchedulePeriod[0].StartPeriod) - require.NotNil(t, confirmation.Schedule.ChargingSchedule.ChargingSchedulePeriod[0].NumberPhases) - assert.Equal(t, *chargingSchedule.ChargingSchedulePeriod[0].NumberPhases, *confirmation.Schedule.ChargingSchedule.ChargingSchedulePeriod[0].NumberPhases) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) + suite.Equal(statusInfo.ReasonCode, confirmation.StatusInfo.ReasonCode) + suite.Require().NotNil(confirmation.Schedule) + suite.Require().NotNil(confirmation.Schedule.StartDateTime) + suite.Equal(compositeSchedule.StartDateTime.FormatTimestamp(), confirmation.Schedule.StartDateTime.FormatTimestamp()) + suite.Require().NotNil(confirmation.Schedule.ChargingSchedule) + suite.Equal(chargingSchedule.ID, confirmation.Schedule.ChargingSchedule.ID) + suite.Equal(chargingSchedule.ChargingRateUnit, confirmation.Schedule.ChargingSchedule.ChargingRateUnit) + suite.Require().NotNil(confirmation.Schedule.ChargingSchedule.Duration) + suite.Equal(*chargingSchedule.Duration, *confirmation.Schedule.ChargingSchedule.Duration) + suite.Require().NotNil(confirmation.Schedule.ChargingSchedule.MinChargingRate) + suite.Equal(*chargingSchedule.MinChargingRate, *confirmation.Schedule.ChargingSchedule.MinChargingRate) + suite.Require().NotNil(confirmation.Schedule.ChargingSchedule.StartSchedule) + suite.Equal(chargingSchedule.StartSchedule.FormatTimestamp(), confirmation.Schedule.ChargingSchedule.StartSchedule.FormatTimestamp()) + suite.Require().Len(confirmation.Schedule.ChargingSchedule.ChargingSchedulePeriod, len(chargingSchedule.ChargingSchedulePeriod)) + suite.Equal(chargingSchedule.ChargingSchedulePeriod[0].Limit, confirmation.Schedule.ChargingSchedule.ChargingSchedulePeriod[0].Limit) + suite.Equal(chargingSchedule.ChargingSchedulePeriod[0].StartPeriod, confirmation.Schedule.ChargingSchedule.ChargingSchedulePeriod[0].StartPeriod) + suite.Require().NotNil(confirmation.Schedule.ChargingSchedule.ChargingSchedulePeriod[0].NumberPhases) + suite.Equal(*chargingSchedule.ChargingSchedulePeriod[0].NumberPhases, *confirmation.Schedule.ChargingSchedule.ChargingSchedulePeriod[0].NumberPhases) resultChannel <- true }, duration, evseID, func(request *smartcharging.GetCompositeScheduleRequest) { request.ChargingRateUnit = chargingRateUnit }) - assert.Nil(t, err) + suite.Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestGetCompositeScheduleInvalidEndpoint() { diff --git a/ocpp2.0.1_test/get_display_messages_test.go b/ocpp2.0.1_test/get_display_messages_test.go index 267c255c..b3e06005 100644 --- a/ocpp2.0.1_test/get_display_messages_test.go +++ b/ocpp2.0.1_test/get_display_messages_test.go @@ -3,16 +3,13 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/display" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/display" ) // Test func (suite *OcppV2TestSuite) TestGetDisplayMessagesRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {display.GetDisplayMessagesRequest{RequestID: 1, Priority: display.MessagePriorityAlwaysFront, State: display.MessageStateCharging, ID: []int{2, 3}}, true}, {display.GetDisplayMessagesRequest{RequestID: 1, Priority: display.MessagePriorityAlwaysFront, State: display.MessageStateCharging, ID: []int{}}, true}, @@ -26,22 +23,20 @@ func (suite *OcppV2TestSuite) TestGetDisplayMessagesRequestValidation() { {display.GetDisplayMessagesRequest{RequestID: 1, Priority: display.MessagePriorityAlwaysFront, State: "invalidMessageState", ID: []int{2, 3}}, false}, {display.GetDisplayMessagesRequest{RequestID: 1, Priority: display.MessagePriorityAlwaysFront, State: display.MessageStateCharging, ID: []int{-2, 3}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestGetDisplayMessagesConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {display.GetDisplayMessagesResponse{Status: display.MessageStatusAccepted}, true}, {display.GetDisplayMessagesResponse{Status: display.MessageStatusUnknown}, true}, {display.GetDisplayMessagesResponse{Status: "invalidMessageStatus"}, false}, {display.GetDisplayMessagesResponse{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestGetDisplayMessagesE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -59,35 +54,35 @@ func (suite *OcppV2TestSuite) TestGetDisplayMessagesE2EMocked() { handler := &MockChargingStationDisplayHandler{} handler.On("OnGetDisplayMessages", mock.Anything).Return(getDisplayMessagesConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*display.GetDisplayMessagesRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, requestId, request.RequestID) - assert.Equal(t, priority, request.Priority) - assert.Equal(t, state, request.State) - require.Len(t, request.ID, len(messageIds)) - assert.Equal(t, messageIds[0], request.ID[0]) - assert.Equal(t, messageIds[1], request.ID[1]) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(requestId, request.RequestID) + suite.Equal(priority, request.Priority) + suite.Equal(state, request.State) + suite.Require().Len(request.ID, len(messageIds)) + suite.Equal(messageIds[0], request.ID[0]) + suite.Equal(messageIds[1], request.ID[1]) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.GetDisplayMessages(wsId, func(confirmation *display.GetDisplayMessagesResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, requestId, func(request *display.GetDisplayMessagesRequest) { request.Priority = priority request.State = state request.ID = messageIds }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestGetDisplayMessagesInvalidEndpoint() { diff --git a/ocpp2.0.1_test/get_installed_certificate_ids_test.go b/ocpp2.0.1_test/get_installed_certificate_ids_test.go index 206cf0b1..81c8bfd3 100644 --- a/ocpp2.0.1_test/get_installed_certificate_ids_test.go +++ b/ocpp2.0.1_test/get_installed_certificate_ids_test.go @@ -3,16 +3,13 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/iso15118" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/iso15118" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) func (suite *OcppV2TestSuite) TestGetInstalledCertificateIdsRequestValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {iso15118.GetInstalledCertificateIdsRequest{CertificateTypes: []types.CertificateUse{types.V2GRootCertificate}}, true}, {iso15118.GetInstalledCertificateIdsRequest{CertificateTypes: []types.CertificateUse{types.MORootCertificate}}, true}, @@ -23,11 +20,10 @@ func (suite *OcppV2TestSuite) TestGetInstalledCertificateIdsRequestValidation() {iso15118.GetInstalledCertificateIdsRequest{}, true}, {iso15118.GetInstalledCertificateIdsRequest{CertificateTypes: []types.CertificateUse{"invalidCertificateUse"}}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestGetInstalledCertificateIdsConfirmationValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {iso15118.GetInstalledCertificateIdsResponse{Status: iso15118.GetInstalledCertificateStatusAccepted, CertificateHashDataChain: []types.CertificateHashDataChain{{CertificateType: types.CSMSRootCertificate, CertificateHashData: types.CertificateHashData{HashAlgorithm: types.SHA256, IssuerNameHash: "name0", IssuerKeyHash: "key0", SerialNumber: "serial0"}}}}, true}, {iso15118.GetInstalledCertificateIdsResponse{Status: iso15118.GetInstalledCertificateStatusNotFound, CertificateHashDataChain: []types.CertificateHashDataChain{{CertificateType: types.CSMSRootCertificate, CertificateHashData: types.CertificateHashData{HashAlgorithm: types.SHA256, IssuerNameHash: "name0", IssuerKeyHash: "key0", SerialNumber: "serial0"}}}}, true}, @@ -37,12 +33,11 @@ func (suite *OcppV2TestSuite) TestGetInstalledCertificateIdsConfirmationValidati {iso15118.GetInstalledCertificateIdsResponse{Status: "invalidGetInstalledCertificateStatus"}, false}, {iso15118.GetInstalledCertificateIdsResponse{Status: iso15118.GetInstalledCertificateStatusAccepted, CertificateHashDataChain: []types.CertificateHashDataChain{{CertificateType: types.CSMSRootCertificate, CertificateHashData: types.CertificateHashData{HashAlgorithm: "invalidHashAlgorithm", IssuerNameHash: "name0", IssuerKeyHash: "key0", SerialNumber: "serial0"}}}}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } // Test func (suite *OcppV2TestSuite) TestGetInstalledCertificateIdsE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -61,33 +56,33 @@ func (suite *OcppV2TestSuite) TestGetInstalledCertificateIdsE2EMocked() { handler := &MockChargingStationIso15118Handler{} handler.On("OnGetInstalledCertificateIds", mock.Anything).Return(getInstalledCertificateIdsConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*iso15118.GetInstalledCertificateIdsRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, certificateTypes, request.CertificateTypes) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(certificateTypes, request.CertificateTypes) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.GetInstalledCertificateIds(wsId, func(confirmation *iso15118.GetInstalledCertificateIdsResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) - require.Len(t, confirmation.CertificateHashDataChain, len(certificateHashDataChain)) - assert.Equal(t, certificateHashDataChain[0].CertificateHashData.HashAlgorithm, confirmation.CertificateHashDataChain[0].CertificateHashData.HashAlgorithm) - assert.Equal(t, certificateHashDataChain[0].CertificateHashData.IssuerNameHash, confirmation.CertificateHashDataChain[0].CertificateHashData.IssuerNameHash) - assert.Equal(t, certificateHashDataChain[0].CertificateHashData.IssuerKeyHash, confirmation.CertificateHashDataChain[0].CertificateHashData.IssuerKeyHash) - assert.Equal(t, certificateHashDataChain[0].CertificateHashData.SerialNumber, confirmation.CertificateHashDataChain[0].CertificateHashData.SerialNumber) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) + suite.Require().Len(confirmation.CertificateHashDataChain, len(certificateHashDataChain)) + suite.Equal(certificateHashDataChain[0].CertificateHashData.HashAlgorithm, confirmation.CertificateHashDataChain[0].CertificateHashData.HashAlgorithm) + suite.Equal(certificateHashDataChain[0].CertificateHashData.IssuerNameHash, confirmation.CertificateHashDataChain[0].CertificateHashData.IssuerNameHash) + suite.Equal(certificateHashDataChain[0].CertificateHashData.IssuerKeyHash, confirmation.CertificateHashDataChain[0].CertificateHashData.IssuerKeyHash) + suite.Equal(certificateHashDataChain[0].CertificateHashData.SerialNumber, confirmation.CertificateHashDataChain[0].CertificateHashData.SerialNumber) resultChannel <- true }, func(request *iso15118.GetInstalledCertificateIdsRequest) { request.CertificateTypes = certificateTypes }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestGetInstalledCertificateIdsInvalidEndpoint() { diff --git a/ocpp2.0.1_test/get_local_list_version_test.go b/ocpp2.0.1_test/get_local_list_version_test.go index 51d1d84b..5232b132 100644 --- a/ocpp2.0.1_test/get_local_list_version_test.go +++ b/ocpp2.0.1_test/get_local_list_version_test.go @@ -3,35 +3,30 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/localauth" ) // Test func (suite *OcppV2TestSuite) TestGetLocalListVersionRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {localauth.GetLocalListVersionRequest{}, true}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestGetLocalListVersionConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {localauth.GetLocalListVersionResponse{VersionNumber: 1}, true}, {localauth.GetLocalListVersionResponse{VersionNumber: 0}, true}, {localauth.GetLocalListVersionResponse{}, true}, {localauth.GetLocalListVersionResponse{VersionNumber: -1}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestGetLocalListVersionE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -48,18 +43,18 @@ func (suite *OcppV2TestSuite) TestGetLocalListVersionE2EMocked() { // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - assert.Nil(t, err) + suite.Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.GetLocalListVersion(wsId, func(confirmation *localauth.GetLocalListVersionResponse, err error) { - assert.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, listVersion, confirmation.VersionNumber) + suite.Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(listVersion, confirmation.VersionNumber) resultChannel <- true }) - assert.Nil(t, err) + suite.Nil(err) if err == nil { result := <-resultChannel - assert.True(t, result) + suite.True(result) } } diff --git a/ocpp2.0.1_test/get_log_test.go b/ocpp2.0.1_test/get_log_test.go index 4aa5ae19..a9fcb45f 100644 --- a/ocpp2.0.1_test/get_log_test.go +++ b/ocpp2.0.1_test/get_log_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestGetLogRequestValidation() { - t := suite.T() logParameters := diagnostics.LogParameters{ RemoteLocation: "ftp://someurl/diagnostics/1", OldestTimestamp: types.NewDateTime(time.Now().Add(-2 * time.Hour)), @@ -34,11 +31,10 @@ func (suite *OcppV2TestSuite) TestGetLogRequestValidation() { {diagnostics.GetLogRequest{LogType: diagnostics.LogTypeDiagnostics, RequestID: 1, Retries: newInt(5), RetryInterval: newInt(-1), Log: logParameters}, false}, {diagnostics.GetLogRequest{LogType: diagnostics.LogTypeDiagnostics, RequestID: 1, Retries: newInt(5), RetryInterval: newInt(120), Log: diagnostics.LogParameters{RemoteLocation: ".invalidUrl.", OldestTimestamp: nil, LatestTimestamp: nil}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestGetLogConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {diagnostics.GetLogResponse{Status: diagnostics.LogStatusAccepted, Filename: "testFileName.log"}, true}, {diagnostics.GetLogResponse{Status: diagnostics.LogStatusAccepted}, true}, @@ -48,11 +44,10 @@ func (suite *OcppV2TestSuite) TestGetLogConfirmationValidation() { {diagnostics.GetLogResponse{Status: "invalidLogStatus"}, false}, {diagnostics.GetLogResponse{Status: diagnostics.LogStatusAccepted, Filename: ">256............................................................................................................................................................................................................................................................."}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestGetLogE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -77,36 +72,36 @@ func (suite *OcppV2TestSuite) TestGetLogE2EMocked() { handler := &MockChargingStationDiagnosticsHandler{} handler.On("OnGetLog", mock.Anything).Return(getLogConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*diagnostics.GetLogRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, logType, request.LogType) - assert.Equal(t, requestID, request.RequestID) - assert.Equal(t, *retries, *request.Retries) - assert.Equal(t, *retryInterval, *request.RetryInterval) - assert.Equal(t, logParameters.RemoteLocation, request.Log.RemoteLocation) - assert.Equal(t, logParameters.LatestTimestamp.FormatTimestamp(), request.Log.LatestTimestamp.FormatTimestamp()) - assert.Equal(t, logParameters.OldestTimestamp.FormatTimestamp(), request.Log.OldestTimestamp.FormatTimestamp()) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(logType, request.LogType) + suite.Equal(requestID, request.RequestID) + suite.Equal(*retries, *request.Retries) + suite.Equal(*retryInterval, *request.RetryInterval) + suite.Equal(logParameters.RemoteLocation, request.Log.RemoteLocation) + suite.Equal(logParameters.LatestTimestamp.FormatTimestamp(), request.Log.LatestTimestamp.FormatTimestamp()) + suite.Equal(logParameters.OldestTimestamp.FormatTimestamp(), request.Log.OldestTimestamp.FormatTimestamp()) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.GetLog(wsId, func(confirmation *diagnostics.GetLogResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) - assert.Equal(t, filename, confirmation.Filename) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) + suite.Equal(filename, confirmation.Filename) resultChannel <- true }, logType, requestID, logParameters, func(request *diagnostics.GetLogRequest) { request.Retries = retries request.RetryInterval = retryInterval }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestGetLogInvalidEndpoint() { diff --git a/ocpp2.0.1_test/get_monitoring_report_test.go b/ocpp2.0.1_test/get_monitoring_report_test.go index bf9f7c69..c56e9d58 100644 --- a/ocpp2.0.1_test/get_monitoring_report_test.go +++ b/ocpp2.0.1_test/get_monitoring_report_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestGetMonitoringReportRequestValidation() { - t := suite.T() componentVariables := []types.ComponentVariable{ { Component: types.Component{Name: "component1", Instance: "instance1", EVSE: &types.EVSE{ID: 2, ConnectorID: newInt(2)}}, @@ -32,21 +29,19 @@ func (suite *OcppV2TestSuite) TestGetMonitoringReportRequestValidation() { {diagnostics.GetMonitoringReportRequest{MonitoringCriteria: []diagnostics.MonitoringCriteriaType{"invalidMonitoringCriteria"}}, false}, {diagnostics.GetMonitoringReportRequest{ComponentVariable: []types.ComponentVariable{{Variable: types.Variable{Name: "variable1", Instance: "instance1"}}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestGetMonitoringReportConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {diagnostics.GetMonitoringReportResponse{Status: types.GenericDeviceModelStatusAccepted}, true}, {diagnostics.GetMonitoringReportResponse{Status: "invalidDeviceModelStatus"}, false}, {diagnostics.GetMonitoringReportResponse{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestGetMonitoringReportE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -67,41 +62,41 @@ func (suite *OcppV2TestSuite) TestGetMonitoringReportE2EMocked() { handler := &MockChargingStationDiagnosticsHandler{} handler.On("OnGetMonitoringReport", mock.Anything).Return(getMonitoringReportConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*diagnostics.GetMonitoringReportRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, *requestID, *request.RequestID) - require.Len(t, request.MonitoringCriteria, len(monitoringCriteria)) - assert.Equal(t, monitoringCriteria[0], request.MonitoringCriteria[0]) - assert.Equal(t, monitoringCriteria[1], request.MonitoringCriteria[1]) - require.Len(t, request.ComponentVariable, len(componentVariables)) - assert.Equal(t, componentVariable.Component.Name, request.ComponentVariable[0].Component.Name) - assert.Equal(t, componentVariable.Component.Instance, request.ComponentVariable[0].Component.Instance) - require.NotNil(t, request.ComponentVariable[0].Component.EVSE) - assert.Equal(t, componentVariable.Component.EVSE.ID, request.ComponentVariable[0].Component.EVSE.ID) - assert.Equal(t, *componentVariable.Component.EVSE.ConnectorID, *request.ComponentVariable[0].Component.EVSE.ConnectorID) - assert.Equal(t, componentVariable.Variable.Name, request.ComponentVariable[0].Variable.Name) - assert.Equal(t, componentVariable.Variable.Instance, request.ComponentVariable[0].Variable.Instance) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(*requestID, *request.RequestID) + suite.Require().Len(request.MonitoringCriteria, len(monitoringCriteria)) + suite.Equal(monitoringCriteria[0], request.MonitoringCriteria[0]) + suite.Equal(monitoringCriteria[1], request.MonitoringCriteria[1]) + suite.Require().Len(request.ComponentVariable, len(componentVariables)) + suite.Equal(componentVariable.Component.Name, request.ComponentVariable[0].Component.Name) + suite.Equal(componentVariable.Component.Instance, request.ComponentVariable[0].Component.Instance) + suite.Require().NotNil(request.ComponentVariable[0].Component.EVSE) + suite.Equal(componentVariable.Component.EVSE.ID, request.ComponentVariable[0].Component.EVSE.ID) + suite.Equal(*componentVariable.Component.EVSE.ConnectorID, *request.ComponentVariable[0].Component.EVSE.ConnectorID) + suite.Equal(componentVariable.Variable.Name, request.ComponentVariable[0].Variable.Name) + suite.Equal(componentVariable.Variable.Instance, request.ComponentVariable[0].Variable.Instance) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.GetMonitoringReport(wsId, func(confirmation *diagnostics.GetMonitoringReportResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, func(request *diagnostics.GetMonitoringReportRequest) { request.RequestID = requestID request.MonitoringCriteria = monitoringCriteria request.ComponentVariable = componentVariables }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestGetMonitoringReportInvalidEndpoint() { diff --git a/ocpp2.0.1_test/get_report_test.go b/ocpp2.0.1_test/get_report_test.go index 2cc85ba7..77268e1e 100644 --- a/ocpp2.0.1_test/get_report_test.go +++ b/ocpp2.0.1_test/get_report_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestGetReportRequestValidation() { - t := suite.T() componentVariables := []types.ComponentVariable{ { Component: types.Component{Name: "component1", Instance: "instance1", EVSE: &types.EVSE{ID: 2, ConnectorID: newInt(2)}}, @@ -32,21 +29,19 @@ func (suite *OcppV2TestSuite) TestGetReportRequestValidation() { {provisioning.GetReportRequest{ComponentCriteria: []provisioning.ComponentCriterion{provisioning.ComponentCriterionActive, provisioning.ComponentCriterionEnabled, provisioning.ComponentCriterionAvailable, provisioning.ComponentCriterionProblem, provisioning.ComponentCriterionActive}}, false}, {provisioning.GetReportRequest{ComponentVariable: []types.ComponentVariable{{Variable: types.Variable{Name: "variable1", Instance: "instance1"}}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestGetReportConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {provisioning.GetReportResponse{Status: types.GenericDeviceModelStatusAccepted}, true}, {provisioning.GetReportResponse{Status: "invalidDeviceModelStatus"}, false}, {provisioning.GetReportResponse{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestGetReportE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -68,41 +63,41 @@ func (suite *OcppV2TestSuite) TestGetReportE2EMocked() { handler := &MockChargingStationProvisioningHandler{} handler.On("OnGetReport", mock.Anything).Return(getReportConfirmation, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*provisioning.GetReportRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, requestID, request.RequestID) - require.Len(t, request.ComponentCriteria, len(componentCriteria)) - assert.Equal(t, componentCriteria[0], request.ComponentCriteria[0]) - assert.Equal(t, componentCriteria[1], request.ComponentCriteria[1]) - require.Len(t, request.ComponentVariable, len(componentVariables)) - assert.Equal(t, componentVariable.Component.Name, request.ComponentVariable[0].Component.Name) - assert.Equal(t, componentVariable.Component.Instance, request.ComponentVariable[0].Component.Instance) - require.NotNil(t, request.ComponentVariable[0].Component.EVSE) - assert.Equal(t, componentVariable.Component.EVSE.ID, request.ComponentVariable[0].Component.EVSE.ID) - assert.Equal(t, *componentVariable.Component.EVSE.ConnectorID, *request.ComponentVariable[0].Component.EVSE.ConnectorID) - assert.Equal(t, componentVariable.Variable.Name, request.ComponentVariable[0].Variable.Name) - assert.Equal(t, componentVariable.Variable.Instance, request.ComponentVariable[0].Variable.Instance) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(requestID, request.RequestID) + suite.Require().Len(request.ComponentCriteria, len(componentCriteria)) + suite.Equal(componentCriteria[0], request.ComponentCriteria[0]) + suite.Equal(componentCriteria[1], request.ComponentCriteria[1]) + suite.Require().Len(request.ComponentVariable, len(componentVariables)) + suite.Equal(componentVariable.Component.Name, request.ComponentVariable[0].Component.Name) + suite.Equal(componentVariable.Component.Instance, request.ComponentVariable[0].Component.Instance) + suite.Require().NotNil(request.ComponentVariable[0].Component.EVSE) + suite.Equal(componentVariable.Component.EVSE.ID, request.ComponentVariable[0].Component.EVSE.ID) + suite.Equal(*componentVariable.Component.EVSE.ConnectorID, *request.ComponentVariable[0].Component.EVSE.ConnectorID) + suite.Equal(componentVariable.Variable.Name, request.ComponentVariable[0].Variable.Name) + suite.Equal(componentVariable.Variable.Instance, request.ComponentVariable[0].Variable.Instance) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.GetReport(wsId, func(confirmation *provisioning.GetReportResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, func(request *provisioning.GetReportRequest) { request.RequestID = requestID request.ComponentCriteria = componentCriteria request.ComponentVariable = componentVariables }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestGetReportInvalidEndpoint() { diff --git a/ocpp2.0.1_test/get_transaction_status_test.go b/ocpp2.0.1_test/get_transaction_status_test.go index 872c35a5..ce3dd318 100644 --- a/ocpp2.0.1_test/get_transaction_status_test.go +++ b/ocpp2.0.1_test/get_transaction_status_test.go @@ -3,36 +3,31 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/transactions" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/transactions" ) // Test func (suite *OcppV2TestSuite) TestGetTransactionStatusRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {transactions.GetTransactionStatusRequest{}, true}, {transactions.GetTransactionStatusRequest{TransactionID: "12345"}, true}, {transactions.GetTransactionStatusRequest{TransactionID: ">36.................................."}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestGetTransactionStatusResponseValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {transactions.GetTransactionStatusResponse{OngoingIndicator: newBool(true), MessagesInQueue: true}, true}, {transactions.GetTransactionStatusResponse{MessagesInQueue: true}, true}, {transactions.GetTransactionStatusResponse{}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestGetTransactionStatusE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -48,30 +43,30 @@ func (suite *OcppV2TestSuite) TestGetTransactionStatusE2EMocked() { handler := &MockChargingStationTransactionHandler{} handler.On("OnGetTransactionStatus", mock.Anything).Return(getTransactionStatusResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*transactions.GetTransactionStatusRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, transactionID, request.TransactionID) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(transactionID, request.TransactionID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.GetTransactionStatus(wsId, func(response *transactions.GetTransactionStatusResponse, err error) { - require.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, messagesInQueue, response.MessagesInQueue) - require.NotNil(t, response.OngoingIndicator) - require.Equal(t, *ongoingIndicator, *response.OngoingIndicator) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Equal(messagesInQueue, response.MessagesInQueue) + suite.Require().NotNil(response.OngoingIndicator) + suite.Require().Equal(*ongoingIndicator, *response.OngoingIndicator) resultChannel <- true }, func(request *transactions.GetTransactionStatusRequest) { request.TransactionID = transactionID }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestGetTransactionStatusInvalidEndpoint() { diff --git a/ocpp2.0.1_test/get_variables_test.go b/ocpp2.0.1_test/get_variables_test.go index 7e202646..eba7db6a 100644 --- a/ocpp2.0.1_test/get_variables_test.go +++ b/ocpp2.0.1_test/get_variables_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestGetVariablesRequestValidation() { - t := suite.T() component := types.Component{Name: "component1", Instance: "instance1", EVSE: &types.EVSE{ID: 2, ConnectorID: newInt(2)}} variable := types.Variable{Name: "variable1", Instance: "instance1"} @@ -29,11 +26,10 @@ func (suite *OcppV2TestSuite) TestGetVariablesRequestValidation() { {provisioning.GetVariablesRequest{GetVariableData: []provisioning.GetVariableData{{AttributeType: types.AttributeTarget, Component: component}}}, false}, {provisioning.GetVariablesRequest{GetVariableData: []provisioning.GetVariableData{{AttributeType: types.AttributeTarget, Component: types.Component{Name: "component1", EVSE: &types.EVSE{ID: -1}}, Variable: variable}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestGetVariablesConfirmationValidation() { - t := suite.T() component := types.Component{Name: "component1", Instance: "instance1", EVSE: &types.EVSE{ID: 2, ConnectorID: newInt(2)}} variable := types.Variable{Name: "variable1", Instance: "instance1"} var confirmationTable = []GenericTestEntry{ @@ -49,11 +45,10 @@ func (suite *OcppV2TestSuite) TestGetVariablesConfirmationValidation() { {provisioning.GetVariablesResponse{GetVariableResult: []provisioning.GetVariableResult{{AttributeStatus: "invalidStatus", AttributeType: types.AttributeTarget, AttributeValue: "dummyValue", Component: component, Variable: variable}}}, false}, {provisioning.GetVariablesResponse{GetVariableResult: []provisioning.GetVariableResult{{AttributeStatus: provisioning.GetVariableStatusAccepted, AttributeType: types.AttributeTarget, AttributeValue: ">1000....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", Component: component, Variable: variable}}}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestGetVariablesE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -82,42 +77,42 @@ func (suite *OcppV2TestSuite) TestGetVariablesE2EMocked() { handler := &MockChargingStationProvisioningHandler{} handler.On("OnGetVariables", mock.Anything).Return(getVariablesResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*provisioning.GetVariablesRequest) - require.True(t, ok) - require.NotNil(t, request) - require.Len(t, request.GetVariableData, 1) - assert.Equal(t, variableData.AttributeType, request.GetVariableData[0].AttributeType) - assert.Equal(t, variableData.Component.Name, request.GetVariableData[0].Component.Name) - assert.Equal(t, variableData.Component.Instance, request.GetVariableData[0].Component.Instance) - assert.Equal(t, variableData.Component.EVSE.ID, request.GetVariableData[0].Component.EVSE.ID) - assert.Equal(t, *variableData.Component.EVSE.ConnectorID, *request.GetVariableData[0].Component.EVSE.ConnectorID) - assert.Equal(t, variableData.Variable.Name, request.GetVariableData[0].Variable.Name) - assert.Equal(t, variableData.Variable.Instance, request.GetVariableData[0].Variable.Instance) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Require().Len(request.GetVariableData, 1) + suite.Equal(variableData.AttributeType, request.GetVariableData[0].AttributeType) + suite.Equal(variableData.Component.Name, request.GetVariableData[0].Component.Name) + suite.Equal(variableData.Component.Instance, request.GetVariableData[0].Component.Instance) + suite.Equal(variableData.Component.EVSE.ID, request.GetVariableData[0].Component.EVSE.ID) + suite.Equal(*variableData.Component.EVSE.ConnectorID, *request.GetVariableData[0].Component.EVSE.ConnectorID) + suite.Equal(variableData.Variable.Name, request.GetVariableData[0].Variable.Name) + suite.Equal(variableData.Variable.Instance, request.GetVariableData[0].Variable.Instance) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.GetVariables(wsId, func(response *provisioning.GetVariablesResponse, err error) { - require.Nil(t, err) - require.NotNil(t, response) - require.Len(t, response.GetVariableResult, 1) - assert.Equal(t, variableResult.AttributeStatus, response.GetVariableResult[0].AttributeStatus) - assert.Equal(t, variableResult.AttributeType, response.GetVariableResult[0].AttributeType) - assert.Equal(t, variableResult.AttributeValue, response.GetVariableResult[0].AttributeValue) - assert.Equal(t, variableResult.Component.Name, response.GetVariableResult[0].Component.Name) - assert.Equal(t, variableResult.Component.Instance, response.GetVariableResult[0].Component.Instance) - assert.Equal(t, variableResult.Component.EVSE.ID, response.GetVariableResult[0].Component.EVSE.ID) - assert.Equal(t, *variableResult.Component.EVSE.ConnectorID, *response.GetVariableResult[0].Component.EVSE.ConnectorID) - assert.Equal(t, variableResult.Variable.Name, response.GetVariableResult[0].Variable.Name) - assert.Equal(t, variableResult.Variable.Instance, response.GetVariableResult[0].Variable.Instance) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Require().Len(response.GetVariableResult, 1) + suite.Equal(variableResult.AttributeStatus, response.GetVariableResult[0].AttributeStatus) + suite.Equal(variableResult.AttributeType, response.GetVariableResult[0].AttributeType) + suite.Equal(variableResult.AttributeValue, response.GetVariableResult[0].AttributeValue) + suite.Equal(variableResult.Component.Name, response.GetVariableResult[0].Component.Name) + suite.Equal(variableResult.Component.Instance, response.GetVariableResult[0].Component.Instance) + suite.Equal(variableResult.Component.EVSE.ID, response.GetVariableResult[0].Component.EVSE.ID) + suite.Equal(*variableResult.Component.EVSE.ConnectorID, *response.GetVariableResult[0].Component.EVSE.ConnectorID) + suite.Equal(variableResult.Variable.Name, response.GetVariableResult[0].Variable.Name) + suite.Equal(variableResult.Variable.Instance, response.GetVariableResult[0].Variable.Instance) resultChannel <- true }, []provisioning.GetVariableData{variableData}) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestGetVariablesInvalidEndpoint() { diff --git a/ocpp2.0.1_test/heartbeat_test.go b/ocpp2.0.1_test/heartbeat_test.go index 1563b85d..1750e293 100644 --- a/ocpp2.0.1_test/heartbeat_test.go +++ b/ocpp2.0.1_test/heartbeat_test.go @@ -4,34 +4,29 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/availability" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/availability" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestHeartbeatRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {availability.HeartbeatRequest{}, true}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestHeartbeatResponseValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {availability.HeartbeatResponse{CurrentTime: *types.NewDateTime(time.Now())}, true}, {availability.HeartbeatResponse{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestHeartbeatE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -44,19 +39,19 @@ func (suite *OcppV2TestSuite) TestHeartbeatE2EMocked() { handler := &MockCSMSAvailabilityHandler{} handler.On("OnHeartbeat", mock.AnythingOfType("string"), mock.Anything).Return(heartbeatResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*availability.HeartbeatRequest) - require.True(t, ok) - require.NotNil(t, request) + suite.Require().True(ok) + suite.Require().NotNil(request) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - assert.Nil(t, err) + suite.Nil(err) response, err := suite.chargingStation.Heartbeat() - assert.Nil(t, err) - assert.NotNil(t, response) - assertDateTimeEquality(t, currentTime, &response.CurrentTime) + suite.Nil(err) + suite.NotNil(response) + assertDateTimeEquality(suite, currentTime, &response.CurrentTime) } func (suite *OcppV2TestSuite) TestHeartbeatInvalidEndpoint() { diff --git a/ocpp2.0.1_test/install_certificate_test.go b/ocpp2.0.1_test/install_certificate_test.go index d4896446..3fe0a316 100644 --- a/ocpp2.0.1_test/install_certificate_test.go +++ b/ocpp2.0.1_test/install_certificate_test.go @@ -3,16 +3,13 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/iso15118" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/iso15118" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) func (suite *OcppV2TestSuite) TestInstallCertificateRequestValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {iso15118.InstallCertificateRequest{CertificateType: types.V2GRootCertificate, Certificate: "0xdeadbeef"}, true}, {iso15118.InstallCertificateRequest{CertificateType: types.MORootCertificate, Certificate: "0xdeadbeef"}, true}, @@ -26,11 +23,10 @@ func (suite *OcppV2TestSuite) TestInstallCertificateRequestValidation() { {iso15118.InstallCertificateRequest{CertificateType: "invalidCertificateUse", Certificate: "0xdeadbeef"}, false}, {iso15118.InstallCertificateRequest{CertificateType: types.V2GRootCertificate, Certificate: newLongString(5501)}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } func (suite *OcppV2TestSuite) TestInstallCertificateConfirmationValidation() { - t := suite.T() var testTable = []GenericTestEntry{ {iso15118.InstallCertificateResponse{Status: iso15118.CertificateStatusAccepted}, true}, {iso15118.InstallCertificateResponse{Status: iso15118.CertificateStatusRejected}, true}, @@ -38,12 +34,11 @@ func (suite *OcppV2TestSuite) TestInstallCertificateConfirmationValidation() { {iso15118.InstallCertificateResponse{}, false}, {iso15118.InstallCertificateResponse{Status: "invalidInstallCertificateStatus"}, false}, } - ExecuteGenericTestTable(t, testTable) + ExecuteGenericTestTable(suite, testTable) } // Test func (suite *OcppV2TestSuite) TestInstallCertificateE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -58,27 +53,27 @@ func (suite *OcppV2TestSuite) TestInstallCertificateE2EMocked() { handler := &MockChargingStationIso15118Handler{} handler.On("OnInstallCertificate", mock.Anything).Return(installCertificateResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*iso15118.InstallCertificateRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, certificateType, request.CertificateType) - assert.Equal(t, certificate, request.Certificate) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(certificateType, request.CertificateType) + suite.Equal(certificate, request.Certificate) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.InstallCertificate(wsId, func(response *iso15118.InstallCertificateResponse, err error) { - require.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, status, response.Status) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Equal(status, response.Status) resultChannel <- true }, certificateType, certificate) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestInstallCertificateInvalidEndpoint() { diff --git a/ocpp2.0.1_test/log_status_notification_test.go b/ocpp2.0.1_test/log_status_notification_test.go index 917bd50a..fee5d27d 100644 --- a/ocpp2.0.1_test/log_status_notification_test.go +++ b/ocpp2.0.1_test/log_status_notification_test.go @@ -3,16 +3,13 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" ) // Test func (suite *OcppV2TestSuite) TestLogStatusNotificationRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {diagnostics.LogStatusNotificationRequest{Status: diagnostics.UploadLogStatusUploading, RequestID: 42}, true}, {diagnostics.LogStatusNotificationRequest{Status: diagnostics.UploadLogStatusUploadFailure, RequestID: 42}, true}, @@ -27,19 +24,17 @@ func (suite *OcppV2TestSuite) TestLogStatusNotificationRequestValidation() { {diagnostics.LogStatusNotificationRequest{Status: diagnostics.UploadLogStatusIdle, RequestID: -1}, false}, {diagnostics.LogStatusNotificationRequest{Status: "invalidUploadLogStatus", RequestID: 42}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestLogStatusNotificationConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {diagnostics.LogStatusNotificationResponse{}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestLogStatusNotificationE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -53,19 +48,19 @@ func (suite *OcppV2TestSuite) TestLogStatusNotificationE2EMocked() { handler := &MockCSMSDiagnosticsHandler{} handler.On("OnLogStatusNotification", mock.AnythingOfType("string"), mock.Anything).Return(logStatusNotificationResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*diagnostics.LogStatusNotificationRequest) - require.True(t, ok) - assert.Equal(t, status, request.Status) - assert.Equal(t, requestID, request.RequestID) + suite.Require().True(ok) + suite.Equal(status, request.Status) + suite.Equal(requestID, request.RequestID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) confirmation, err := suite.chargingStation.LogStatusNotification(status, requestID) - assert.Nil(t, err) - assert.NotNil(t, confirmation) + suite.Nil(err) + suite.NotNil(confirmation) } func (suite *OcppV2TestSuite) TestLogStatusNotificationInvalidEndpoint() { diff --git a/ocpp2.0.1_test/meter_values_test.go b/ocpp2.0.1_test/meter_values_test.go index 0e7ae7bb..11a5cd8b 100644 --- a/ocpp2.0.1_test/meter_values_test.go +++ b/ocpp2.0.1_test/meter_values_test.go @@ -4,12 +4,10 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/meter" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/meter" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test @@ -22,18 +20,17 @@ func (suite *OcppV2TestSuite) TestMeterValuesRequestValidation() { {meter.MeterValuesRequest{EvseID: 1, MeterValue: []types.MeterValue{{Timestamp: types.DateTime{Time: time.Now()}, SampledValue: []types.SampledValue{{Value: 3.14, Context: "invalidContext", Measurand: types.MeasurandPowerActiveExport, Phase: types.PhaseL2, Location: types.LocationBody}}}}}, false}, {meter.MeterValuesRequest{EvseID: -1, MeterValue: []types.MeterValue{{Timestamp: types.DateTime{Time: time.Now()}, SampledValue: []types.SampledValue{{Value: 3.14, Context: types.ReadingContextTransactionEnd, Measurand: types.MeasurandPowerActiveExport, Phase: types.PhaseL2, Location: types.LocationBody}}}}}, false}, } - ExecuteGenericTestTable(suite.T(), requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestMeterValuesConfirmationValidation() { var responseTable = []GenericTestEntry{ {meter.MeterValuesResponse{}, true}, } - ExecuteGenericTestTable(suite.T(), responseTable) + ExecuteGenericTestTable(suite, responseTable) } func (suite *OcppV2TestSuite) TestMeterValuesE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -54,33 +51,33 @@ func (suite *OcppV2TestSuite) TestMeterValuesE2EMocked() { handler := &MockCSMSMeterHandler{} handler.On("OnMeterValues", mock.AnythingOfType("string"), mock.Anything).Return(response, nil).Run(func(args mock.Arguments) { request := args.Get(1).(*meter.MeterValuesRequest) - assert.Equal(t, evseId, request.EvseID) - require.Len(t, request.MeterValue, len(meterValues)) - assertDateTimeEquality(t, &meterValue.Timestamp, &request.MeterValue[0].Timestamp) - require.Len(t, request.MeterValue[0].SampledValue, len(sampledValues)) - assert.Equal(t, sampledValue.Value, request.MeterValue[0].SampledValue[0].Value) - assert.Equal(t, sampledValue.Context, request.MeterValue[0].SampledValue[0].Context) - assert.Equal(t, sampledValue.Measurand, request.MeterValue[0].SampledValue[0].Measurand) - assert.Equal(t, sampledValue.Phase, request.MeterValue[0].SampledValue[0].Phase) - assert.Equal(t, sampledValue.Location, request.MeterValue[0].SampledValue[0].Location) - require.NotNil(t, request.MeterValue[0].SampledValue[0].SignedMeterValue) - assert.Equal(t, signedMeterValue.SignedMeterData, request.MeterValue[0].SampledValue[0].SignedMeterValue.SignedMeterData) - assert.Equal(t, signedMeterValue.SigningMethod, request.MeterValue[0].SampledValue[0].SignedMeterValue.SigningMethod) - assert.Equal(t, signedMeterValue.EncodingMethod, request.MeterValue[0].SampledValue[0].SignedMeterValue.EncodingMethod) - assert.Equal(t, signedMeterValue.PublicKey, request.MeterValue[0].SampledValue[0].SignedMeterValue.PublicKey) - require.NotNil(t, request.MeterValue[0].SampledValue[0].UnitOfMeasure) - assert.Equal(t, unitOfMeasure.Unit, request.MeterValue[0].SampledValue[0].UnitOfMeasure.Unit) - assert.Equal(t, *unitOfMeasure.Multiplier, *request.MeterValue[0].SampledValue[0].UnitOfMeasure.Multiplier) + suite.Equal(evseId, request.EvseID) + suite.Require().Len(request.MeterValue, len(meterValues)) + assertDateTimeEquality(suite, &meterValue.Timestamp, &request.MeterValue[0].Timestamp) + suite.Require().Len(request.MeterValue[0].SampledValue, len(sampledValues)) + suite.Equal(sampledValue.Value, request.MeterValue[0].SampledValue[0].Value) + suite.Equal(sampledValue.Context, request.MeterValue[0].SampledValue[0].Context) + suite.Equal(sampledValue.Measurand, request.MeterValue[0].SampledValue[0].Measurand) + suite.Equal(sampledValue.Phase, request.MeterValue[0].SampledValue[0].Phase) + suite.Equal(sampledValue.Location, request.MeterValue[0].SampledValue[0].Location) + suite.Require().NotNil(request.MeterValue[0].SampledValue[0].SignedMeterValue) + suite.Equal(signedMeterValue.SignedMeterData, request.MeterValue[0].SampledValue[0].SignedMeterValue.SignedMeterData) + suite.Equal(signedMeterValue.SigningMethod, request.MeterValue[0].SampledValue[0].SignedMeterValue.SigningMethod) + suite.Equal(signedMeterValue.EncodingMethod, request.MeterValue[0].SampledValue[0].SignedMeterValue.EncodingMethod) + suite.Equal(signedMeterValue.PublicKey, request.MeterValue[0].SampledValue[0].SignedMeterValue.PublicKey) + suite.Require().NotNil(request.MeterValue[0].SampledValue[0].UnitOfMeasure) + suite.Equal(unitOfMeasure.Unit, request.MeterValue[0].SampledValue[0].UnitOfMeasure.Unit) + suite.Equal(*unitOfMeasure.Multiplier, *request.MeterValue[0].SampledValue[0].UnitOfMeasure.Multiplier) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - assert.Nil(t, err) + suite.Nil(err) r, err := suite.chargingStation.MeterValues(evseId, meterValues) - assert.Nil(t, err) - assert.NotNil(t, r) + suite.Nil(err) + suite.NotNil(r) } func (suite *OcppV2TestSuite) TestMeterValuesInvalidEndpoint() { diff --git a/ocpp2.0.1_test/notify_charging_limit_test.go b/ocpp2.0.1_test/notify_charging_limit_test.go index ab03b9d6..566358e4 100644 --- a/ocpp2.0.1_test/notify_charging_limit_test.go +++ b/ocpp2.0.1_test/notify_charging_limit_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Tests func (suite *OcppV2TestSuite) TestNotifyChargingLimitRequestValidation() { - t := suite.T() chargingSchedule := types.ChargingSchedule{ ID: 1, StartSchedule: types.NewDateTime(time.Now()), @@ -35,19 +32,17 @@ func (suite *OcppV2TestSuite) TestNotifyChargingLimitRequestValidation() { {smartcharging.NotifyChargingLimitRequest{EvseID: newInt(-1), ChargingLimit: smartcharging.ChargingLimit{ChargingLimitSource: types.ChargingLimitSourceEMS, IsGridCritical: newBool(false)}}, false}, {smartcharging.NotifyChargingLimitRequest{ChargingLimit: smartcharging.ChargingLimit{ChargingLimitSource: types.ChargingLimitSourceEMS, IsGridCritical: newBool(false)}, ChargingSchedule: []types.ChargingSchedule{{ChargingRateUnit: "invalidStruct"}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestNotifyChargingLimitResponseValidation() { - t := suite.T() var responseTable = []GenericTestEntry{ {smartcharging.NotifyChargingLimitResponse{}, true}, } - ExecuteGenericTestTable(t, responseTable) + ExecuteGenericTestTable(suite, responseTable) } func (suite *OcppV2TestSuite) TestNotifyChargingLimitE2EMocked() { - t := suite.T() wsId := "test_id" messageId := "1234" wsUrl := "someUrl" @@ -71,34 +66,34 @@ func (suite *OcppV2TestSuite) TestNotifyChargingLimitE2EMocked() { handler := &MockCSMSSmartChargingHandler{} handler.On("OnNotifyChargingLimit", mock.AnythingOfType("string"), mock.Anything).Return(response, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*smartcharging.NotifyChargingLimitRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, *evseID, *request.EvseID) - assert.Equal(t, chargingLimit.ChargingLimitSource, request.ChargingLimit.ChargingLimitSource) - require.NotNil(t, request.ChargingLimit.IsGridCritical) - assert.Equal(t, chargingLimit.IsGridCritical, request.ChargingLimit.IsGridCritical) - require.Len(t, request.ChargingSchedule, len(chargingSchedules)) - assertDateTimeEquality(t, chargingSchedule.StartSchedule, request.ChargingSchedule[0].StartSchedule) - assert.Equal(t, chargingSchedule.ID, request.ChargingSchedule[0].ID) - assert.Equal(t, *chargingSchedule.Duration, *request.ChargingSchedule[0].Duration) - assert.Equal(t, chargingSchedule.ChargingRateUnit, request.ChargingSchedule[0].ChargingRateUnit) - assert.Equal(t, *chargingSchedule.MinChargingRate, *request.ChargingSchedule[0].MinChargingRate) - assert.Len(t, request.ChargingSchedule[0].ChargingSchedulePeriod, len(chargingSchedule.ChargingSchedulePeriod)) - assert.Equal(t, chargingSchedule.ChargingSchedulePeriod[0].StartPeriod, request.ChargingSchedule[0].ChargingSchedulePeriod[0].StartPeriod) - assert.Equal(t, chargingSchedule.ChargingSchedulePeriod[0].Limit, request.ChargingSchedule[0].ChargingSchedulePeriod[0].Limit) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(*evseID, *request.EvseID) + suite.Equal(chargingLimit.ChargingLimitSource, request.ChargingLimit.ChargingLimitSource) + suite.Require().NotNil(request.ChargingLimit.IsGridCritical) + suite.Equal(chargingLimit.IsGridCritical, request.ChargingLimit.IsGridCritical) + suite.Require().Len(request.ChargingSchedule, len(chargingSchedules)) + assertDateTimeEquality(suite, chargingSchedule.StartSchedule, request.ChargingSchedule[0].StartSchedule) + suite.Equal(chargingSchedule.ID, request.ChargingSchedule[0].ID) + suite.Equal(*chargingSchedule.Duration, *request.ChargingSchedule[0].Duration) + suite.Equal(chargingSchedule.ChargingRateUnit, request.ChargingSchedule[0].ChargingRateUnit) + suite.Equal(*chargingSchedule.MinChargingRate, *request.ChargingSchedule[0].MinChargingRate) + suite.Require().Len(request.ChargingSchedule[0].ChargingSchedulePeriod, len(chargingSchedule.ChargingSchedulePeriod)) + suite.Equal(chargingSchedule.ChargingSchedulePeriod[0].StartPeriod, request.ChargingSchedule[0].ChargingSchedulePeriod[0].StartPeriod) + suite.Equal(chargingSchedule.ChargingSchedulePeriod[0].Limit, request.ChargingSchedule[0].ChargingSchedulePeriod[0].Limit) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) r, err := suite.chargingStation.NotifyChargingLimit(chargingLimit, func(request *smartcharging.NotifyChargingLimitRequest) { request.EvseID = evseID request.ChargingSchedule = chargingSchedules }) - require.Nil(t, err) - require.NotNil(t, r) + suite.Require().Nil(err) + suite.Require().NotNil(r) } func (suite *OcppV2TestSuite) TestNotifyChargingLimitInvalidEndpoint() { diff --git a/ocpp2.0.1_test/notify_customer_information_test.go b/ocpp2.0.1_test/notify_customer_information_test.go index f012a7c6..d46b18da 100644 --- a/ocpp2.0.1_test/notify_customer_information_test.go +++ b/ocpp2.0.1_test/notify_customer_information_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestNotifyCustomerInformationRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {diagnostics.NotifyCustomerInformationRequest{Data: "dummyData", Tbc: false, SeqNo: 0, GeneratedAt: types.DateTime{Time: time.Now()}, RequestID: 42}, true}, {diagnostics.NotifyCustomerInformationRequest{Data: "dummyData", Tbc: true, SeqNo: 0, GeneratedAt: types.DateTime{Time: time.Now()}, RequestID: 42}, true}, @@ -27,19 +24,17 @@ func (suite *OcppV2TestSuite) TestNotifyCustomerInformationRequestValidation() { {diagnostics.NotifyCustomerInformationRequest{Data: "dummyData", Tbc: false, SeqNo: -1, GeneratedAt: types.DateTime{Time: time.Now()}, RequestID: 42}, false}, {diagnostics.NotifyCustomerInformationRequest{Data: "dummyData", Tbc: false, SeqNo: 0, GeneratedAt: types.DateTime{Time: time.Now()}, RequestID: -1}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestNotifyCustomerInformationConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {diagnostics.NotifyCustomerInformationResponse{}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestNotifyCustomerInformationE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -57,22 +52,22 @@ func (suite *OcppV2TestSuite) TestNotifyCustomerInformationE2EMocked() { handler := &MockCSMSDiagnosticsHandler{} handler.On("OnNotifyCustomerInformation", mock.AnythingOfType("string"), mock.Anything).Return(response, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*diagnostics.NotifyCustomerInformationRequest) - require.True(t, ok) - assert.Equal(t, data, request.Data) - assert.Equal(t, tbc, request.Tbc) - assert.Equal(t, seqNo, request.SeqNo) - assertDateTimeEquality(t, &generatedAt, &request.GeneratedAt) - assert.Equal(t, requestID, request.RequestID) + suite.Require().True(ok) + suite.Equal(data, request.Data) + suite.Equal(tbc, request.Tbc) + suite.Equal(seqNo, request.SeqNo) + assertDateTimeEquality(suite, &generatedAt, &request.GeneratedAt) + suite.Equal(requestID, request.RequestID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) r, err := suite.chargingStation.NotifyCustomerInformation(data, seqNo, generatedAt, requestID) - assert.Nil(t, err) - assert.NotNil(t, r) + suite.Nil(err) + suite.NotNil(r) } func (suite *OcppV2TestSuite) TestNotifyCustomerInformationInvalidEndpoint() { diff --git a/ocpp2.0.1_test/notify_display_messages_test.go b/ocpp2.0.1_test/notify_display_messages_test.go index a28e2070..6d2aa539 100644 --- a/ocpp2.0.1_test/notify_display_messages_test.go +++ b/ocpp2.0.1_test/notify_display_messages_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/display" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/display" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestNotifyDisplayMessagesRequestValidation() { - t := suite.T() messageInfo := display.MessageInfo{ID: 42, Priority: display.MessagePriorityAlwaysFront, State: display.MessageStateIdle, Message: types.MessageContent{Format: types.MessageFormatUTF8, Content: "hello world"}} var requestTable = []GenericTestEntry{ {display.NotifyDisplayMessagesRequest{RequestID: 42, Tbc: false, MessageInfo: []display.MessageInfo{messageInfo}}, true}, @@ -25,19 +22,17 @@ func (suite *OcppV2TestSuite) TestNotifyDisplayMessagesRequestValidation() { {display.NotifyDisplayMessagesRequest{RequestID: -1}, false}, {display.NotifyDisplayMessagesRequest{RequestID: 42, MessageInfo: []display.MessageInfo{{ID: 42, Priority: "invalidPriority", State: display.MessageStateIdle, Message: types.MessageContent{Format: types.MessageFormatUTF8, Content: "hello world"}}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestNotifyDisplayMessagesConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {display.NotifyDisplayMessagesResponse{}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestNotifyDisplayMessagesE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -53,29 +48,29 @@ func (suite *OcppV2TestSuite) TestNotifyDisplayMessagesE2EMocked() { handler := &MockCSMSDisplayHandler{} handler.On("OnNotifyDisplayMessages", mock.AnythingOfType("string"), mock.Anything).Return(response, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*display.NotifyDisplayMessagesRequest) - require.True(t, ok) - assert.Equal(t, requestID, request.RequestID) - assert.Equal(t, tbc, request.Tbc) - require.Len(t, request.MessageInfo, 1) - assert.Equal(t, messageInfo.ID, request.MessageInfo[0].ID) - assert.Equal(t, messageInfo.Priority, request.MessageInfo[0].Priority) - assert.Equal(t, messageInfo.State, request.MessageInfo[0].State) - assertDateTimeEquality(t, messageInfo.StartDateTime, request.MessageInfo[0].StartDateTime) - assert.Equal(t, messageInfo.Message.Format, request.MessageInfo[0].Message.Format) - assert.Equal(t, messageInfo.Message.Content, request.MessageInfo[0].Message.Content) - assert.Equal(t, messageInfo.Message.Language, request.MessageInfo[0].Message.Language) + suite.Require().True(ok) + suite.Equal(requestID, request.RequestID) + suite.Equal(tbc, request.Tbc) + suite.Require().Len(request.MessageInfo, 1) + suite.Equal(messageInfo.ID, request.MessageInfo[0].ID) + suite.Equal(messageInfo.Priority, request.MessageInfo[0].Priority) + suite.Equal(messageInfo.State, request.MessageInfo[0].State) + assertDateTimeEquality(suite, messageInfo.StartDateTime, request.MessageInfo[0].StartDateTime) + suite.Equal(messageInfo.Message.Format, request.MessageInfo[0].Message.Format) + suite.Equal(messageInfo.Message.Content, request.MessageInfo[0].Message.Content) + suite.Equal(messageInfo.Message.Language, request.MessageInfo[0].Message.Language) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) r, err := suite.chargingStation.NotifyDisplayMessages(requestID, func(request *display.NotifyDisplayMessagesRequest) { request.MessageInfo = []display.MessageInfo{messageInfo} }) - assert.Nil(t, err) - assert.NotNil(t, r) + suite.Nil(err) + suite.NotNil(r) } func (suite *OcppV2TestSuite) TestNotifyDisplayMessagesInvalidEndpoint() { diff --git a/ocpp2.0.1_test/notify_ev_charging_needs_test.go b/ocpp2.0.1_test/notify_ev_charging_needs_test.go index ceaeaa77..d93b80db 100644 --- a/ocpp2.0.1_test/notify_ev_charging_needs_test.go +++ b/ocpp2.0.1_test/notify_ev_charging_needs_test.go @@ -4,16 +4,13 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) func (suite *OcppV2TestSuite) TestNotifyEVChargingNeedsRequestValidation() { - t := suite.T() chargingNeeds := smartcharging.ChargingNeeds{ RequestedEnergyTransfer: smartcharging.EnergyTransferModeAC3Phase, DepartureTime: types.NewDateTime(time.Now()), @@ -48,11 +45,10 @@ func (suite *OcppV2TestSuite) TestNotifyEVChargingNeedsRequestValidation() { {smartcharging.NotifyEVChargingNeedsRequest{EvseID: 1, ChargingNeeds: smartcharging.ChargingNeeds{RequestedEnergyTransfer: smartcharging.EnergyTransferModeAC3Phase, ACChargingParameters: &smartcharging.ACChargingParameters{EnergyAmount: -1}}}, false}, {smartcharging.NotifyEVChargingNeedsRequest{EvseID: 1, ChargingNeeds: smartcharging.ChargingNeeds{RequestedEnergyTransfer: smartcharging.EnergyTransferModeDC, DCChargingParameters: &smartcharging.DCChargingParameters{EVMaxCurrent: -1}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestDCChargingParametersValidation() { - t := suite.T() var table = []GenericTestEntry{ {&smartcharging.DCChargingParameters{EVMaxCurrent: 0, EVMaxVoltage: 0, EnergyAmount: newInt(42), EVMaxPower: newInt(150), StateOfCharge: newInt(50), EVEnergyCapacity: newInt(42), FullSoC: newInt(100), BulkSoC: newInt(80)}, true}, {&smartcharging.DCChargingParameters{EVMaxCurrent: 0, EVMaxVoltage: 0}, true}, @@ -69,11 +65,10 @@ func (suite *OcppV2TestSuite) TestDCChargingParametersValidation() { {&smartcharging.DCChargingParameters{EVMaxCurrent: 0, EVMaxVoltage: 0, EnergyAmount: newInt(42), EVMaxPower: newInt(150), StateOfCharge: newInt(101), EVEnergyCapacity: newInt(42), FullSoC: newInt(100), BulkSoC: newInt(80)}, false}, {&smartcharging.DCChargingParameters{EVMaxCurrent: 0, EVMaxVoltage: 0, EnergyAmount: newInt(42), EVMaxPower: newInt(150), StateOfCharge: newInt(50), EVEnergyCapacity: newInt(42), FullSoC: newInt(100), BulkSoC: newInt(101)}, false}, } - ExecuteGenericTestTable(t, table) + ExecuteGenericTestTable(suite, table) } func (suite *OcppV2TestSuite) TestACChargingParametersValidation() { - t := suite.T() var table = []GenericTestEntry{ {&smartcharging.ACChargingParameters{EnergyAmount: 42, EVMinCurrent: 6, EVMaxCurrent: 20, EVMaxVoltage: 400}, true}, {&smartcharging.ACChargingParameters{}, true}, @@ -82,11 +77,10 @@ func (suite *OcppV2TestSuite) TestACChargingParametersValidation() { {&smartcharging.ACChargingParameters{EnergyAmount: 0, EVMinCurrent: 0, EVMaxCurrent: -1, EVMaxVoltage: 0}, false}, {&smartcharging.ACChargingParameters{EnergyAmount: 0, EVMinCurrent: 0, EVMaxCurrent: 0, EVMaxVoltage: -1}, false}, } - ExecuteGenericTestTable(t, table) + ExecuteGenericTestTable(suite, table) } func (suite *OcppV2TestSuite) TestNotifyEVChargingNeedsConfirmationValidation() { - t := suite.T() var responseTable = []GenericTestEntry{ {smartcharging.NotifyEVChargingNeedsResponse{Status: smartcharging.EVChargingNeedsStatusAccepted, StatusInfo: types.NewStatusInfo("ok", "someInfo")}, true}, {smartcharging.NotifyEVChargingNeedsResponse{Status: smartcharging.EVChargingNeedsStatusAccepted}, true}, @@ -96,11 +90,10 @@ func (suite *OcppV2TestSuite) TestNotifyEVChargingNeedsConfirmationValidation() {smartcharging.NotifyEVChargingNeedsResponse{Status: "invalidStatus"}, false}, {smartcharging.NotifyEVChargingNeedsResponse{Status: smartcharging.EVChargingNeedsStatusAccepted, StatusInfo: types.NewStatusInfo("", "invalidStatusInfo")}, false}, } - ExecuteGenericTestTable(t, responseTable) + ExecuteGenericTestTable(suite, responseTable) } func (suite *OcppV2TestSuite) TestNotifyEVChargingNeedsE2EMocked() { - t := suite.T() wsId := "test_id" messageId := "1234" wsUrl := "someUrl" @@ -131,31 +124,31 @@ func (suite *OcppV2TestSuite) TestNotifyEVChargingNeedsE2EMocked() { handler := &MockCSMSSmartChargingHandler{} handler.On("OnNotifyEVChargingNeeds", mock.AnythingOfType("string"), mock.Anything).Return(notifyEVChargingNeedsResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*smartcharging.NotifyEVChargingNeedsRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, *maxScheduleTuples, *request.MaxScheduleTuples) - assert.Equal(t, evseID, request.EvseID) - assert.Equal(t, chargingNeeds.RequestedEnergyTransfer, request.ChargingNeeds.RequestedEnergyTransfer) - assert.Equal(t, chargingNeeds.DepartureTime.FormatTimestamp(), request.ChargingNeeds.DepartureTime.FormatTimestamp()) - assert.Equal(t, acChargingParams.EnergyAmount, request.ChargingNeeds.ACChargingParameters.EnergyAmount) - assert.Equal(t, acChargingParams.EVMinCurrent, request.ChargingNeeds.ACChargingParameters.EVMinCurrent) - assert.Equal(t, acChargingParams.EVMaxCurrent, request.ChargingNeeds.ACChargingParameters.EVMaxCurrent) - assert.Equal(t, acChargingParams.EVMaxVoltage, request.ChargingNeeds.ACChargingParameters.EVMaxVoltage) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(*maxScheduleTuples, *request.MaxScheduleTuples) + suite.Equal(evseID, request.EvseID) + suite.Equal(chargingNeeds.RequestedEnergyTransfer, request.ChargingNeeds.RequestedEnergyTransfer) + suite.Equal(chargingNeeds.DepartureTime.FormatTimestamp(), request.ChargingNeeds.DepartureTime.FormatTimestamp()) + suite.Equal(acChargingParams.EnergyAmount, request.ChargingNeeds.ACChargingParameters.EnergyAmount) + suite.Equal(acChargingParams.EVMinCurrent, request.ChargingNeeds.ACChargingParameters.EVMinCurrent) + suite.Equal(acChargingParams.EVMaxCurrent, request.ChargingNeeds.ACChargingParameters.EVMaxCurrent) + suite.Equal(acChargingParams.EVMaxVoltage, request.ChargingNeeds.ACChargingParameters.EVMaxVoltage) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) response, err := suite.chargingStation.NotifyEVChargingNeeds(evseID, chargingNeeds, func(request *smartcharging.NotifyEVChargingNeedsRequest) { request.MaxScheduleTuples = maxScheduleTuples }) - require.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, status, response.Status) - assert.Equal(t, statusInfo.ReasonCode, response.StatusInfo.ReasonCode) - assert.Equal(t, statusInfo.AdditionalInfo, response.StatusInfo.AdditionalInfo) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Equal(status, response.Status) + suite.Equal(statusInfo.ReasonCode, response.StatusInfo.ReasonCode) + suite.Equal(statusInfo.AdditionalInfo, response.StatusInfo.AdditionalInfo) } func (suite *OcppV2TestSuite) TestNotifyEVChargingNeedsInvalidEndpoint() { diff --git a/ocpp2.0.1_test/notify_ev_charging_schedule_test.go b/ocpp2.0.1_test/notify_ev_charging_schedule_test.go index 2ab8dffe..6de818e5 100644 --- a/ocpp2.0.1_test/notify_ev_charging_schedule_test.go +++ b/ocpp2.0.1_test/notify_ev_charging_schedule_test.go @@ -4,16 +4,13 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) func (suite *OcppV2TestSuite) TestNotifyEVChargingScheduleRequestValidation() { - t := suite.T() chargingSchedule := types.ChargingSchedule{ StartSchedule: types.NewDateTime(time.Now()), Duration: newInt(600), @@ -31,11 +28,10 @@ func (suite *OcppV2TestSuite) TestNotifyEVChargingScheduleRequestValidation() { {smartcharging.NotifyEVChargingScheduleRequest{TimeBase: types.NewDateTime(time.Now()), EvseID: -1, ChargingSchedule: chargingSchedule}, false}, {smartcharging.NotifyEVChargingScheduleRequest{TimeBase: types.NewDateTime(time.Now()), EvseID: -1, ChargingSchedule: types.ChargingSchedule{ChargingRateUnit: "invalidStruct"}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestNotifyEVChargingScheduleResponseValidation() { - t := suite.T() var responseTable = []GenericTestEntry{ {smartcharging.NotifyEVChargingScheduleResponse{Status: types.GenericStatusAccepted, StatusInfo: types.NewStatusInfo("ok", "someInfo")}, true}, {smartcharging.NotifyEVChargingScheduleResponse{Status: types.GenericStatusRejected, StatusInfo: types.NewStatusInfo("ok", "someInfo")}, true}, @@ -44,11 +40,10 @@ func (suite *OcppV2TestSuite) TestNotifyEVChargingScheduleResponseValidation() { {smartcharging.NotifyEVChargingScheduleResponse{Status: "invalidStatus"}, false}, {smartcharging.NotifyEVChargingScheduleResponse{Status: types.GenericStatusAccepted, StatusInfo: types.NewStatusInfo("", "invalidStatusInfo")}, false}, } - ExecuteGenericTestTable(t, responseTable) + ExecuteGenericTestTable(suite, responseTable) } func (suite *OcppV2TestSuite) TestNotifyEVChargingScheduleE2EMocked() { - t := suite.T() wsId := "test_id" messageId := "1234" wsUrl := "someUrl" @@ -75,33 +70,33 @@ func (suite *OcppV2TestSuite) TestNotifyEVChargingScheduleE2EMocked() { handler := &MockCSMSSmartChargingHandler{} handler.On("OnNotifyEVChargingSchedule", mock.AnythingOfType("string"), mock.Anything).Return(notifyEVChargingScheduleResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*smartcharging.NotifyEVChargingScheduleRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, timeBase.FormatTimestamp(), request.TimeBase.FormatTimestamp()) - assert.Equal(t, evseID, request.EvseID) - assert.Equal(t, chargingSchedule.ID, request.ChargingSchedule.ID) - assert.Equal(t, chargingSchedule.StartSchedule.FormatTimestamp(), request.ChargingSchedule.StartSchedule.FormatTimestamp()) - assert.Equal(t, *chargingSchedule.Duration, *request.ChargingSchedule.Duration) - assert.Equal(t, *chargingSchedule.MinChargingRate, *request.ChargingSchedule.MinChargingRate) - assert.Equal(t, *chargingSchedule.MinChargingRate, *request.ChargingSchedule.MinChargingRate) - assert.Equal(t, chargingSchedule.ChargingRateUnit, request.ChargingSchedule.ChargingRateUnit) - require.Len(t, request.ChargingSchedule.ChargingSchedulePeriod, len(request.ChargingSchedule.ChargingSchedulePeriod)) - assert.Equal(t, chargingSchedule.ChargingSchedulePeriod[0].StartPeriod, request.ChargingSchedule.ChargingSchedulePeriod[0].StartPeriod) - assert.Equal(t, chargingSchedule.ChargingSchedulePeriod[0].Limit, request.ChargingSchedule.ChargingSchedulePeriod[0].Limit) - assert.Nil(t, request.ChargingSchedule.ChargingSchedulePeriod[0].NumberPhases) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(timeBase.FormatTimestamp(), request.TimeBase.FormatTimestamp()) + suite.Equal(evseID, request.EvseID) + suite.Equal(chargingSchedule.ID, request.ChargingSchedule.ID) + suite.Equal(chargingSchedule.StartSchedule.FormatTimestamp(), request.ChargingSchedule.StartSchedule.FormatTimestamp()) + suite.Equal(*chargingSchedule.Duration, *request.ChargingSchedule.Duration) + suite.Equal(*chargingSchedule.MinChargingRate, *request.ChargingSchedule.MinChargingRate) + suite.Equal(*chargingSchedule.MinChargingRate, *request.ChargingSchedule.MinChargingRate) + suite.Equal(chargingSchedule.ChargingRateUnit, request.ChargingSchedule.ChargingRateUnit) + suite.Require().Len(request.ChargingSchedule.ChargingSchedulePeriod, len(request.ChargingSchedule.ChargingSchedulePeriod)) + suite.Equal(chargingSchedule.ChargingSchedulePeriod[0].StartPeriod, request.ChargingSchedule.ChargingSchedulePeriod[0].StartPeriod) + suite.Equal(chargingSchedule.ChargingSchedulePeriod[0].Limit, request.ChargingSchedule.ChargingSchedulePeriod[0].Limit) + suite.Nil(request.ChargingSchedule.ChargingSchedulePeriod[0].NumberPhases) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) response, err := suite.chargingStation.NotifyEVChargingSchedule(timeBase, evseID, chargingSchedule) - require.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, status, response.Status) - assert.Equal(t, statusInfo.ReasonCode, response.StatusInfo.ReasonCode) - assert.Equal(t, statusInfo.AdditionalInfo, response.StatusInfo.AdditionalInfo) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Equal(status, response.Status) + suite.Equal(statusInfo.ReasonCode, response.StatusInfo.ReasonCode) + suite.Equal(statusInfo.AdditionalInfo, response.StatusInfo.AdditionalInfo) } func (suite *OcppV2TestSuite) TestNotifyEVChargingScheduleInvalidEndpoint() { diff --git a/ocpp2.0.1_test/notify_event_test.go b/ocpp2.0.1_test/notify_event_test.go index 3c1e124d..c07cbdfb 100644 --- a/ocpp2.0.1_test/notify_event_test.go +++ b/ocpp2.0.1_test/notify_event_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestNotifyEventRequestValidation() { - t := suite.T() eventData := diagnostics.EventData{ EventID: 1, Timestamp: types.NewDateTime(time.Now()), @@ -42,11 +39,10 @@ func (suite *OcppV2TestSuite) TestNotifyEventRequestValidation() { {diagnostics.NotifyEventRequest{GeneratedAt: types.NewDateTime(time.Now()), SeqNo: 0, Tbc: false}, false}, {diagnostics.NotifyEventRequest{GeneratedAt: types.NewDateTime(time.Now()), SeqNo: 0, Tbc: false, EventData: []diagnostics.EventData{{Timestamp: types.NewDateTime(time.Now()), Trigger: diagnostics.EventTriggerAlerting, Cause: newInt(42), ActualValue: "someValue", Component: types.Component{Name: "component1"}, Variable: types.Variable{Name: "variable1"}}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestNotifyEventDataValidation() { - t := suite.T() var table = []GenericTestEntry{ {diagnostics.EventData{EventID: 1, Timestamp: types.NewDateTime(time.Now()), Trigger: diagnostics.EventTriggerAlerting, Cause: newInt(42), ActualValue: "someValue", TechCode: "742", TechInfo: "stacktrace", Cleared: false, TransactionID: "1234", VariableMonitoringID: newInt(99), EventNotificationType: diagnostics.EventPreconfiguredMonitor, Component: types.Component{Name: "component1"}, Variable: types.Variable{Name: "variable1"}}, true}, {diagnostics.EventData{EventID: 1, Timestamp: types.NewDateTime(time.Now()), Trigger: diagnostics.EventTriggerAlerting, Cause: newInt(42), ActualValue: "someValue", TechCode: "742", TechInfo: "stacktrace", Cleared: false, TransactionID: "1234", EventNotificationType: diagnostics.EventPreconfiguredMonitor, Component: types.Component{Name: "component1"}, Variable: types.Variable{Name: "variable1"}}, true}, @@ -71,19 +67,17 @@ func (suite *OcppV2TestSuite) TestNotifyEventDataValidation() { {diagnostics.EventData{EventID: 1, Timestamp: types.NewDateTime(time.Now()), Trigger: diagnostics.EventTriggerAlerting, Cause: newInt(42), ActualValue: "someValue", TechCode: "742", TechInfo: "stacktrace", Cleared: false, TransactionID: "1234", VariableMonitoringID: newInt(99), EventNotificationType: diagnostics.EventPreconfiguredMonitor, Component: types.Component{Name: ">50................................................"}, Variable: types.Variable{Name: "variable1"}}, false}, {diagnostics.EventData{EventID: 1, Timestamp: types.NewDateTime(time.Now()), Trigger: diagnostics.EventTriggerAlerting, Cause: newInt(42), ActualValue: "someValue", TechCode: "742", TechInfo: "stacktrace", Cleared: false, TransactionID: "1234", VariableMonitoringID: newInt(99), EventNotificationType: diagnostics.EventPreconfiguredMonitor, Component: types.Component{Name: "component1"}, Variable: types.Variable{Name: ">50................................................"}}, false}, } - ExecuteGenericTestTable(t, table) + ExecuteGenericTestTable(suite, table) } func (suite *OcppV2TestSuite) TestNotifyEventResponseValidation() { - t := suite.T() var responseTable = []GenericTestEntry{ {diagnostics.NotifyEventResponse{}, true}, } - ExecuteGenericTestTable(t, responseTable) + ExecuteGenericTestTable(suite, responseTable) } func (suite *OcppV2TestSuite) TestNotifyEventE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -114,36 +108,36 @@ func (suite *OcppV2TestSuite) TestNotifyEventE2EMocked() { handler := &MockCSMSDiagnosticsHandler{} handler.On("OnNotifyEvent", mock.AnythingOfType("string"), mock.Anything).Return(response, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*diagnostics.NotifyEventRequest) - require.True(t, ok) - assertDateTimeEquality(t, generatedAt, request.GeneratedAt) - assert.Equal(t, tbc, request.Tbc) - assert.Equal(t, seqNo, request.SeqNo) - require.Len(t, request.EventData, 1) - assert.Equal(t, eventData.EventID, request.EventData[0].EventID) - assertDateTimeEquality(t, eventData.Timestamp, request.EventData[0].Timestamp) - assert.Equal(t, eventData.Trigger, request.EventData[0].Trigger) - assert.Equal(t, *eventData.Cause, *request.EventData[0].Cause) - assert.Equal(t, eventData.ActualValue, request.EventData[0].ActualValue) - assert.Equal(t, eventData.TechCode, request.EventData[0].TechCode) - assert.Equal(t, eventData.TechInfo, request.EventData[0].TechInfo) - assert.Equal(t, eventData.Cleared, request.EventData[0].Cleared) - assert.Equal(t, eventData.TransactionID, request.EventData[0].TransactionID) - assert.Equal(t, *eventData.VariableMonitoringID, *request.EventData[0].VariableMonitoringID) - assert.Equal(t, eventData.EventNotificationType, request.EventData[0].EventNotificationType) - assert.Equal(t, eventData.Component.Name, request.EventData[0].Component.Name) - assert.Equal(t, eventData.Variable.Name, request.EventData[0].Variable.Name) + suite.Require().True(ok) + assertDateTimeEquality(suite, generatedAt, request.GeneratedAt) + suite.Equal(tbc, request.Tbc) + suite.Equal(seqNo, request.SeqNo) + suite.Require().Len(request.EventData, 1) + suite.Equal(eventData.EventID, request.EventData[0].EventID) + assertDateTimeEquality(suite, eventData.Timestamp, request.EventData[0].Timestamp) + suite.Equal(eventData.Trigger, request.EventData[0].Trigger) + suite.Equal(*eventData.Cause, *request.EventData[0].Cause) + suite.Equal(eventData.ActualValue, request.EventData[0].ActualValue) + suite.Equal(eventData.TechCode, request.EventData[0].TechCode) + suite.Equal(eventData.TechInfo, request.EventData[0].TechInfo) + suite.Equal(eventData.Cleared, request.EventData[0].Cleared) + suite.Equal(eventData.TransactionID, request.EventData[0].TransactionID) + suite.Equal(*eventData.VariableMonitoringID, *request.EventData[0].VariableMonitoringID) + suite.Equal(eventData.EventNotificationType, request.EventData[0].EventNotificationType) + suite.Equal(eventData.Component.Name, request.EventData[0].Component.Name) + suite.Equal(eventData.Variable.Name, request.EventData[0].Variable.Name) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) r, err := suite.chargingStation.NotifyEvent(generatedAt, seqNo, []diagnostics.EventData{eventData}, func(request *diagnostics.NotifyEventRequest) { request.Tbc = tbc }) - assert.Nil(t, err) - assert.NotNil(t, r) + suite.Nil(err) + suite.NotNil(r) } func (suite *OcppV2TestSuite) TestNotifyEventInvalidEndpoint() { diff --git a/ocpp2.0.1_test/notify_monitoring_report_test.go b/ocpp2.0.1_test/notify_monitoring_report_test.go index ddcd525e..092c694f 100644 --- a/ocpp2.0.1_test/notify_monitoring_report_test.go +++ b/ocpp2.0.1_test/notify_monitoring_report_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestNotifyMonitoringReportRequestValidation() { - t := suite.T() validMonitoring := diagnostics.NewVariableMonitoring(1, false, 42.42, diagnostics.MonitorPeriodic, 0) invalidMonitoring := diagnostics.NewVariableMonitoring(1, false, 42.42, "invalidMonitorType", 0) monitoringData := diagnostics.MonitoringData{ @@ -36,11 +33,10 @@ func (suite *OcppV2TestSuite) TestNotifyMonitoringReportRequestValidation() { {diagnostics.NotifyMonitoringReportRequest{RequestID: 42, Tbc: true, SeqNo: 0, GeneratedAt: types.NewDateTime(time.Now()), Monitor: []diagnostics.MonitoringData{{Component: types.Component{Name: "component1"}, Variable: types.Variable{Name: "variable1"}, VariableMonitoring: []diagnostics.VariableMonitoring{}}}}, false}, {diagnostics.NotifyMonitoringReportRequest{RequestID: 42, Tbc: true, SeqNo: 0, GeneratedAt: types.NewDateTime(time.Now()), Monitor: []diagnostics.MonitoringData{{Component: types.Component{Name: "component1"}, Variable: types.Variable{}, VariableMonitoring: []diagnostics.VariableMonitoring{validMonitoring}}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestVariableMonitoringValidation() { - t := suite.T() var table = []GenericTestEntry{ {diagnostics.VariableMonitoring{ID: 1, Transaction: false, Value: 42.42, Type: diagnostics.MonitorPeriodic, Severity: 0}, true}, {diagnostics.VariableMonitoring{ID: 1, Transaction: false, Value: 42.42, Type: diagnostics.MonitorPeriodic, Severity: 9}, true}, @@ -59,19 +55,17 @@ func (suite *OcppV2TestSuite) TestVariableMonitoringValidation() { {diagnostics.VariableMonitoring{ID: 1, Transaction: false, Value: 42.42, Type: diagnostics.MonitorPeriodic, Severity: 10}, false}, {diagnostics.VariableMonitoring{ID: 1, Transaction: false, Value: 42.42, Type: "invalidMonitorType", Severity: 0}, false}, } - ExecuteGenericTestTable(t, table) + ExecuteGenericTestTable(suite, table) } func (suite *OcppV2TestSuite) TestNotifyMonitoringReportResponseValidation() { - t := suite.T() var responseTable = []GenericTestEntry{ {diagnostics.NotifyMonitoringReportResponse{}, true}, } - ExecuteGenericTestTable(t, responseTable) + ExecuteGenericTestTable(suite, responseTable) } func (suite *OcppV2TestSuite) TestNotifyMonitoringReportE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -94,32 +88,32 @@ func (suite *OcppV2TestSuite) TestNotifyMonitoringReportE2EMocked() { handler := &MockCSMSDiagnosticsHandler{} handler.On("OnNotifyMonitoringReport", mock.AnythingOfType("string"), mock.Anything).Return(response, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*diagnostics.NotifyMonitoringReportRequest) - require.True(t, ok) - assert.Equal(t, requestID, request.RequestID) - assert.Equal(t, tbc, request.Tbc) - assert.Equal(t, seqNo, request.SeqNo) - assertDateTimeEquality(t, generatedAt, request.GeneratedAt) - require.Len(t, request.Monitor, 1) - assert.Equal(t, monitoringData.Component.Name, request.Monitor[0].Component.Name) - assert.Equal(t, monitoringData.Variable.Name, request.Monitor[0].Variable.Name) - require.Len(t, request.Monitor[0].VariableMonitoring, len(monitoringData.VariableMonitoring)) - assert.Equal(t, monitoringData.VariableMonitoring[0].ID, request.Monitor[0].VariableMonitoring[0].ID) - assert.Equal(t, monitoringData.VariableMonitoring[0].Transaction, request.Monitor[0].VariableMonitoring[0].Transaction) - assert.Equal(t, monitoringData.VariableMonitoring[0].Type, request.Monitor[0].VariableMonitoring[0].Type) - assert.Equal(t, monitoringData.VariableMonitoring[0].Value, request.Monitor[0].VariableMonitoring[0].Value) - assert.Equal(t, monitoringData.VariableMonitoring[0].Severity, request.Monitor[0].VariableMonitoring[0].Severity) + suite.Require().True(ok) + suite.Equal(requestID, request.RequestID) + suite.Equal(tbc, request.Tbc) + suite.Equal(seqNo, request.SeqNo) + assertDateTimeEquality(suite, generatedAt, request.GeneratedAt) + suite.Require().Len(request.Monitor, 1) + suite.Equal(monitoringData.Component.Name, request.Monitor[0].Component.Name) + suite.Equal(monitoringData.Variable.Name, request.Monitor[0].Variable.Name) + suite.Require().Len(request.Monitor[0].VariableMonitoring, len(monitoringData.VariableMonitoring)) + suite.Equal(monitoringData.VariableMonitoring[0].ID, request.Monitor[0].VariableMonitoring[0].ID) + suite.Equal(monitoringData.VariableMonitoring[0].Transaction, request.Monitor[0].VariableMonitoring[0].Transaction) + suite.Equal(monitoringData.VariableMonitoring[0].Type, request.Monitor[0].VariableMonitoring[0].Type) + suite.Equal(monitoringData.VariableMonitoring[0].Value, request.Monitor[0].VariableMonitoring[0].Value) + suite.Equal(monitoringData.VariableMonitoring[0].Severity, request.Monitor[0].VariableMonitoring[0].Severity) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) r, err := suite.chargingStation.NotifyMonitoringReport(requestID, seqNo, generatedAt, []diagnostics.MonitoringData{monitoringData}, func(request *diagnostics.NotifyMonitoringReportRequest) { request.Tbc = tbc }) - assert.Nil(t, err) - assert.NotNil(t, r) + suite.Nil(err) + suite.NotNil(r) } func (suite *OcppV2TestSuite) TestNotifyMonitoringReportInvalidEndpoint() { diff --git a/ocpp2.0.1_test/notify_report_test.go b/ocpp2.0.1_test/notify_report_test.go index ce2e536e..a749ed59 100644 --- a/ocpp2.0.1_test/notify_report_test.go +++ b/ocpp2.0.1_test/notify_report_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Tests func (suite *OcppV2TestSuite) TestNotifyReportRequestValidation() { - t := suite.T() reportData := provisioning.ReportData{ Component: types.Component{Name: "component1"}, Variable: types.Variable{Name: "variable1"}, @@ -40,11 +37,10 @@ func (suite *OcppV2TestSuite) TestNotifyReportRequestValidation() { {provisioning.NotifyReportRequest{RequestID: 42, GeneratedAt: types.NewDateTime(time.Now()), Tbc: true, SeqNo: 0, ReportData: []provisioning.ReportData{{Component: types.Component{Name: "comp1"}, Variable: types.Variable{Name: "var1"}, VariableAttribute: []provisioning.VariableAttribute{provisioning.NewVariableAttribute()}, VariableCharacteristics: provisioning.NewVariableCharacteristics("unknownType", true)}}}, false}, {provisioning.NotifyReportRequest{RequestID: 42, GeneratedAt: types.NewDateTime(time.Now()), Tbc: true, SeqNo: 0, ReportData: []provisioning.ReportData{{Component: types.Component{Name: "comp1"}, Variable: types.Variable{Name: "var1"}, VariableAttribute: []provisioning.VariableAttribute{{Mutability: "invalidMutability"}}, VariableCharacteristics: provisioning.NewVariableCharacteristics(provisioning.TypeString, true)}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestVariableCharacteristicsValidation() { - t := suite.T() var table = []GenericTestEntry{ {provisioning.NewVariableCharacteristics(provisioning.TypeString, false), true}, {provisioning.VariableCharacteristics{Unit: "KWh", DataType: provisioning.TypeDecimal, MinLimit: newFloat(1.0), MaxLimit: newFloat(22.0), ValuesList: "7.0", SupportsMonitoring: true}, true}, @@ -66,11 +62,10 @@ func (suite *OcppV2TestSuite) TestVariableCharacteristicsValidation() { {provisioning.VariableCharacteristics{Unit: "KWh", DataType: "invalidDataType", MinLimit: newFloat(1.0), MaxLimit: newFloat(22.0), ValuesList: "7.0", SupportsMonitoring: true}, false}, {provisioning.VariableCharacteristics{Unit: "KWh", DataType: provisioning.TypeDecimal, MinLimit: newFloat(1.0), MaxLimit: newFloat(22.0), ValuesList: ">1000....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", SupportsMonitoring: true}, false}, } - ExecuteGenericTestTable(t, table) + ExecuteGenericTestTable(suite, table) } func (suite *OcppV2TestSuite) TestVariableAttributeValidation() { - t := suite.T() var table = []GenericTestEntry{ {provisioning.NewVariableAttribute(), true}, {provisioning.VariableAttribute{Type: types.AttributeActual, Value: "someValue", Mutability: provisioning.MutabilityReadWrite, Persistent: false, Constant: false}, true}, @@ -91,20 +86,18 @@ func (suite *OcppV2TestSuite) TestVariableAttributeValidation() { {provisioning.VariableAttribute{Type: types.AttributeActual, Value: "someValue", Mutability: "invalidMutability"}, false}, {provisioning.VariableAttribute{Type: types.AttributeActual, Value: ">2500................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", Mutability: provisioning.MutabilityReadWrite}, false}, } - ExecuteGenericTestTable(t, table) + ExecuteGenericTestTable(suite, table) } func (suite *OcppV2TestSuite) TestNotifyReportResponseValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {provisioning.NewNotifyReportResponse(), true}, {provisioning.NotifyReportResponse{}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestNotifyReportE2EMocked() { - t := suite.T() wsId := "test_id" messageId := "1234" wsUrl := "someUrl" @@ -129,37 +122,37 @@ func (suite *OcppV2TestSuite) TestNotifyReportE2EMocked() { handler := &MockCSMSProvisioningHandler{} handler.On("OnNotifyReport", mock.AnythingOfType("string"), mock.Anything).Return(notifyReportResponse, nil).Run(func(args mock.Arguments) { request := args.Get(1).(*provisioning.NotifyReportRequest) - assert.Equal(t, requestID, request.RequestID) - assertDateTimeEquality(t, generatedAt, request.GeneratedAt) - assert.Equal(t, seqNo, request.SeqNo) - assert.Equal(t, tbc, request.Tbc) - require.Len(t, request.ReportData, 1) - assert.Equal(t, reportData.Component.Name, request.ReportData[0].Component.Name) - assert.Equal(t, reportData.Variable.Name, request.ReportData[0].Variable.Name) - require.Len(t, request.ReportData[0].VariableAttribute, len(reportData.VariableAttribute)) - assert.Equal(t, variableAttribute.Mutability, request.ReportData[0].VariableAttribute[0].Mutability) - assert.Equal(t, variableAttribute.Value, request.ReportData[0].VariableAttribute[0].Value) - assert.Equal(t, variableAttribute.Type, request.ReportData[0].VariableAttribute[0].Type) - assert.Equal(t, variableAttribute.Constant, request.ReportData[0].VariableAttribute[0].Constant) - assert.Equal(t, variableAttribute.Persistent, request.ReportData[0].VariableAttribute[0].Persistent) - require.NotNil(t, request.ReportData[0].VariableCharacteristics) - assert.Equal(t, variableCharacteristics.Unit, request.ReportData[0].VariableCharacteristics.Unit) - assert.Equal(t, variableCharacteristics.DataType, request.ReportData[0].VariableCharacteristics.DataType) - assert.Equal(t, *variableCharacteristics.MaxLimit, *request.ReportData[0].VariableCharacteristics.MaxLimit) - assert.Equal(t, variableCharacteristics.SupportsMonitoring, request.ReportData[0].VariableCharacteristics.SupportsMonitoring) + suite.Equal(requestID, request.RequestID) + assertDateTimeEquality(suite, generatedAt, request.GeneratedAt) + suite.Equal(seqNo, request.SeqNo) + suite.Equal(tbc, request.Tbc) + suite.Require().Len(request.ReportData, 1) + suite.Equal(reportData.Component.Name, request.ReportData[0].Component.Name) + suite.Equal(reportData.Variable.Name, request.ReportData[0].Variable.Name) + suite.Require().Len(request.ReportData[0].VariableAttribute, len(reportData.VariableAttribute)) + suite.Equal(variableAttribute.Mutability, request.ReportData[0].VariableAttribute[0].Mutability) + suite.Equal(variableAttribute.Value, request.ReportData[0].VariableAttribute[0].Value) + suite.Equal(variableAttribute.Type, request.ReportData[0].VariableAttribute[0].Type) + suite.Equal(variableAttribute.Constant, request.ReportData[0].VariableAttribute[0].Constant) + suite.Equal(variableAttribute.Persistent, request.ReportData[0].VariableAttribute[0].Persistent) + suite.Require().NotNil(request.ReportData[0].VariableCharacteristics) + suite.Equal(variableCharacteristics.Unit, request.ReportData[0].VariableCharacteristics.Unit) + suite.Equal(variableCharacteristics.DataType, request.ReportData[0].VariableCharacteristics.DataType) + suite.Equal(*variableCharacteristics.MaxLimit, *request.ReportData[0].VariableCharacteristics.MaxLimit) + suite.Equal(variableCharacteristics.SupportsMonitoring, request.ReportData[0].VariableCharacteristics.SupportsMonitoring) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) response, err := suite.chargingStation.NotifyReport(requestID, generatedAt, seqNo, func(request *provisioning.NotifyReportRequest) { request.ReportData = []provisioning.ReportData{reportData} request.Tbc = tbc }) - require.Nil(t, err) - require.NotNil(t, response) + suite.Require().Nil(err) + suite.Require().NotNil(response) } func (suite *OcppV2TestSuite) TestNotifyReportInvalidEndpoint() { diff --git a/ocpp2.0.1_test/ocpp2_test.go b/ocpp2.0.1_test/ocpp2_test.go index ee769483..0d3ec420 100644 --- a/ocpp2.0.1_test/ocpp2_test.go +++ b/ocpp2.0.1_test/ocpp2_test.go @@ -9,32 +9,31 @@ import ( "time" "github.com/sirupsen/logrus" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" - - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/authorization" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/availability" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/data" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/display" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/iso15118" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/meter" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/remotecontrol" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/security" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/tariffcost" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/transactions" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" - "github.com/lorenzodonini/ocpp-go/ocppj" - "github.com/lorenzodonini/ocpp-go/ws" + "go.opentelemetry.io/otel/metric/noop" + + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/authorization" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/availability" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/data" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/display" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/iso15118" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/meter" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/remotecontrol" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/security" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/tariffcost" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/transactions" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ws" ) // ---------------------- MOCK WEBSOCKET ---------------------- @@ -835,7 +834,6 @@ type expectedChargingStationOptions struct { } func setupDefaultCSMSHandlers(suite *OcppV2TestSuite, options expectedCSMSOptions, handlers ...interface{}) { - t := suite.T() for _, h := range handlers { switch h := h.(type) { case *MockCSMSAuthorizationHandler: @@ -873,7 +871,7 @@ func setupDefaultCSMSHandlers(suite *OcppV2TestSuite, options expectedCSMSOption } } suite.csms.SetNewChargingStationHandler(func(chargingStation ocpp2.ChargingStationConnection) { - assert.Equal(t, options.clientId, chargingStation.ID()) + suite.Equal(options.clientId, chargingStation.ID()) }) suite.mockWsServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(options.startReturnArgument) suite.mockWsServer.On("Stop").Return() @@ -881,21 +879,20 @@ func setupDefaultCSMSHandlers(suite *OcppV2TestSuite, options expectedCSMSOption clientId := args.String(0) data := args.Get(1) bytes := data.([]byte) - assert.Equal(t, options.clientId, clientId) + suite.Equal(options.clientId, clientId) if options.rawWrittenMessage != nil { - assert.NotNil(t, bytes) - assert.Equal(t, string(options.rawWrittenMessage), string(bytes)) + suite.NotNil(bytes) + suite.Equal(string(options.rawWrittenMessage), string(bytes)) } if options.forwardWrittenMessage { // Notify client of incoming response err := suite.mockWsClient.MessageHandler(bytes) - assert.Nil(t, err) + suite.Nil(err) } }) } func setupDefaultChargingStationHandlers(suite *OcppV2TestSuite, options expectedChargingStationOptions, handlers ...interface{}) { - t := suite.T() for _, h := range handlers { switch h := h.(type) { case *MockChargingStationAuthorizationHandler: @@ -934,7 +931,7 @@ func setupDefaultChargingStationHandlers(suite *OcppV2TestSuite, options expecte } suite.mockWsClient.On("Start", mock.AnythingOfType("string")).Return(options.startReturnArgument).Run(func(args mock.Arguments) { u := args.String(0) - assert.Equal(t, fmt.Sprintf("%s/%s", options.serverUrl, options.clientId), u) + suite.Equal(fmt.Sprintf("%s/%s", options.serverUrl, options.clientId), u) // Notify server of incoming connection if options.createChannelOnStart { suite.mockWsServer.NewClientHandler(options.channel) @@ -944,19 +941,19 @@ func setupDefaultChargingStationHandlers(suite *OcppV2TestSuite, options expecte data := args.Get(0) bytes := data.([]byte) if options.rawWrittenMessage != nil { - assert.NotNil(t, bytes) - assert.Equal(t, string(options.rawWrittenMessage), string(bytes)) + suite.NotNil(bytes) + suite.Equal(string(options.rawWrittenMessage), string(bytes)) } // Notify server of incoming request if options.forwardWrittenMessage { err := suite.mockWsServer.MessageHandler(options.channel, bytes) - assert.Nil(t, err) + suite.Nil(err) } }) } -func assertDateTimeEquality(t *testing.T, expected *types.DateTime, actual *types.DateTime) { - assert.Equal(t, expected.FormatTimestamp(), actual.FormatTimestamp()) +func assertDateTimeEquality(suite *OcppV2TestSuite, expected *types.DateTime, actual *types.DateTime) { + suite.Equal(expected.FormatTimestamp(), actual.FormatTimestamp()) } func testUnsupportedRequestFromChargingStation(suite *OcppV2TestSuite, request ocpp.Request, requestJson string, messageId string, handlers ...interface{}) { @@ -972,29 +969,29 @@ func testUnsupportedRequestFromChargingStation(suite *OcppV2TestSuite, request o setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(errorJson), forwardWrittenMessage: true}, handlers...) resultChannel := make(chan bool, 1) suite.ocppjClient.SetErrorHandler(func(err *ocpp.Error, details interface{}) { - assert.Equal(t, messageId, err.MessageId) - assert.Equal(t, ocppj.NotSupported, err.Code) - assert.Equal(t, errorDescription, err.Description) - assert.Equal(t, map[string]interface{}{}, details) + suite.Equal(messageId, err.MessageId) + suite.Equal(ocppj.NotSupported, err.Code) + suite.Equal(errorDescription, err.Description) + suite.Equal(map[string]interface{}{}, details) resultChannel <- true }) // Start suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) // 1. Test sending an unsupported request, expecting an error err = suite.chargingStation.SendRequestAsync(request, func(confirmation ocpp.Response, err error) { t.Fail() }) - require.Error(t, err) - assert.Equal(t, expectedError, err.Error()) + suite.Require().Error(err) + suite.Equal(expectedError, err.Error()) // 2. Test receiving an unsupported request on the other endpoint and receiving an error // Mark mocked request as pending, otherwise response will be ignored suite.ocppjClient.RequestState.AddPendingRequest(messageId, request) err = suite.mockWsServer.MessageHandler(channel, []byte(requestJson)) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) // Stop the CSMS suite.csms.Stop() } @@ -1012,31 +1009,31 @@ func testUnsupportedRequestFromCentralSystem(suite *OcppV2TestSuite, request ocp setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(errorJson), forwardWrittenMessage: true}, handlers...) resultChannel := make(chan struct{}, 1) suite.ocppjServer.SetErrorHandler(func(channel ws.Channel, err *ocpp.Error, details interface{}) { - assert.Equal(t, messageId, err.MessageId) - assert.Equal(t, wsId, channel.ID()) - assert.Equal(t, ocppj.NotSupported, err.Code) - assert.Equal(t, errorDescription, err.Description) - assert.Equal(t, map[string]interface{}{}, details) + suite.Equal(messageId, err.MessageId) + suite.Equal(wsId, channel.ID()) + suite.Equal(ocppj.NotSupported, err.Code) + suite.Equal(errorDescription, err.Description) + suite.Equal(map[string]interface{}{}, details) resultChannel <- struct{}{} }) // Start suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) // 1. Test sending an unsupported request, expecting an error err = suite.csms.SendRequestAsync(wsId, request, func(response ocpp.Response, err error) { t.Fail() }) - require.Error(t, err) - assert.Equal(t, expectedError, err.Error()) + suite.Require().Error(err) + suite.Equal(expectedError, err.Error()) // 2. Test receiving an unsupported request on the other endpoint and receiving an error // Mark mocked request as pending, otherwise response will be ignored suite.ocppjServer.RequestState.AddPendingRequest(wsId, messageId, request) // Run response test err = suite.mockWsClient.MessageHandler([]byte(requestJson)) - assert.Nil(t, err) + suite.Nil(err) _, ok := <-resultChannel - assert.True(t, ok) + suite.True(ok) // Stop the CSMS suite.csms.Stop() } @@ -1047,13 +1044,13 @@ type GenericTestEntry struct { } // TODO: pass expected error value for improved validation and error message -func ExecuteGenericTestTable(t *testing.T, testTable []GenericTestEntry) { +func ExecuteGenericTestTable(suite *OcppV2TestSuite, testTable []GenericTestEntry) { for _, testCase := range testTable { err := types.Validate.Struct(testCase.Element) if err != nil { - assert.Equal(t, testCase.ExpectedValid, false, err.Error()) + suite.Equal(false, testCase.ExpectedValid, err.Error()) } else { - assert.Equal(t, testCase.ExpectedValid, true, "%v is valid", testCase.Element) + suite.Equal(true, testCase.ExpectedValid, "%v is valid", testCase.Element) } } } @@ -1102,14 +1099,19 @@ func (suite *OcppV2TestSuite) SetupTest() { transactionsProfile := transactions.Profile mockClient := MockWebsocketClient{} mockServer := MockWebsocketServer{} + var err error suite.mockWsClient = &mockClient suite.mockWsServer = &mockServer - suite.clientDispatcher = ocppj.NewDefaultClientDispatcher(ocppj.NewFIFOClientQueue(queueCapacity)) - suite.serverDispatcher = ocppj.NewDefaultServerDispatcher(ocppj.NewFIFOQueueMap(queueCapacity)) - suite.ocppjClient = ocppj.NewClient("test_id", suite.mockWsClient, suite.clientDispatcher, nil, securityProfile, provisioningProfile, authProfile, availabilityProfile, reservationProfile, diagnosticsProfile, dataProfile, displayProfile, firmwareProfile, isoProfile, localAuthProfile, meterProfile, remoteProfile, smartChargingProfile, tariffProfile, transactionsProfile) - suite.ocppjServer = ocppj.NewServer(suite.mockWsServer, suite.serverDispatcher, nil, securityProfile, provisioningProfile, authProfile, availabilityProfile, reservationProfile, diagnosticsProfile, dataProfile, displayProfile, firmwareProfile, isoProfile, localAuthProfile, meterProfile, remoteProfile, smartChargingProfile, tariffProfile, transactionsProfile) - suite.chargingStation = ocpp2.NewChargingStation("test_id", suite.ocppjClient, suite.mockWsClient) - suite.csms = ocpp2.NewCSMS(suite.ocppjServer, suite.mockWsServer) + suite.clientDispatcher = ocppj.NewDefaultClientDispatcher(ocppj.NewFIFOClientQueue(queueCapacity), nil) + suite.serverDispatcher = ocppj.NewDefaultServerDispatcher(ocppj.NewFIFOQueueMap(queueCapacity), noop.NewMeterProvider(), nil) + suite.ocppjClient, err = ocppj.NewClient("test_id", suite.mockWsClient, suite.clientDispatcher, nil, nil, securityProfile, provisioningProfile, authProfile, availabilityProfile, reservationProfile, diagnosticsProfile, dataProfile, displayProfile, firmwareProfile, isoProfile, localAuthProfile, meterProfile, remoteProfile, smartChargingProfile, tariffProfile, transactionsProfile) + suite.Require().NoError(err) + suite.ocppjServer, err = ocppj.NewServer(suite.mockWsServer, suite.serverDispatcher, nil, nil, securityProfile, provisioningProfile, authProfile, availabilityProfile, reservationProfile, diagnosticsProfile, dataProfile, displayProfile, firmwareProfile, isoProfile, localAuthProfile, meterProfile, remoteProfile, smartChargingProfile, tariffProfile, transactionsProfile) + suite.Require().NoError(err) + suite.chargingStation, err = ocpp2.NewChargingStation("test_id", suite.ocppjClient, suite.mockWsClient, nil) + suite.Require().NoError(err) + suite.csms, err = ocpp2.NewCSMS(suite.ocppjServer, suite.mockWsServer, nil) + suite.Require().NoError(err) suite.messageIdGenerator = TestRandomIdGenerator{generator: func() string { return defaultMessageId }} @@ -1118,13 +1120,12 @@ func (suite *OcppV2TestSuite) SetupTest() { } func (suite *OcppV2TestSuite) TestIsConnected() { - t := suite.T() // Simulate ws connected mockCall := suite.mockWsClient.On("IsConnected").Return(true) - assert.True(t, suite.chargingStation.IsConnected()) + suite.True(suite.chargingStation.IsConnected()) // Simulate ws disconnected mockCall.Return(false) - assert.False(t, suite.chargingStation.IsConnected()) + suite.False(suite.chargingStation.IsConnected()) } //TODO: implement generic protocol tests diff --git a/ocpp2.0.1_test/proto_test.go b/ocpp2.0.1_test/proto_test.go index 38669a35..8a4af528 100644 --- a/ocpp2.0.1_test/proto_test.go +++ b/ocpp2.0.1_test/proto_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/data" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/data" - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocppj" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocppj" ) func (suite *OcppV2TestSuite) TestChargePointSendResponseError() { - t := suite.T() wsId := "test_id" channel := NewMockWebSocket(wsId) var ocppErr *ocpp.Error @@ -28,19 +25,19 @@ func (suite *OcppV2TestSuite) TestChargePointSendResponseError() { rawMsg := args.Get(0) bytes := rawMsg.([]byte) err := suite.mockWsServer.MessageHandler(channel, bytes) - assert.Nil(t, err) + suite.Nil(err) }) suite.mockWsServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) suite.mockWsServer.On("Write", mock.AnythingOfType("string"), mock.Anything).Return(nil).Run(func(args mock.Arguments) { rawMsg := args.Get(1) bytes := rawMsg.([]byte) err := suite.mockWsClient.MessageHandler(bytes) - assert.NoError(t, err) + suite.NoError(err) }) // Run Tests suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start("someUrl") - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan error, 1) // Test 1: occurrence validation error dataTransferResponse := data.NewDataTransferResponse(data.DataTransferStatusAccepted) @@ -49,50 +46,49 @@ func (suite *OcppV2TestSuite) TestChargePointSendResponseError() { }{Field1: ""} dataListener.On("OnDataTransfer", mock.Anything).Return(dataTransferResponse, nil) err = suite.csms.DataTransfer(wsId, func(response *data.DataTransferResponse, err error) { - require.Nil(t, response) - require.Error(t, err) + suite.Require().Nil(response) + suite.Require().Error(err) resultChannel <- err }, "vendor1") - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - require.IsType(t, &ocpp.Error{}, result) + suite.Require().IsType(&ocpp.Error{}, result) ocppErr = result.(*ocpp.Error) - assert.Equal(t, ocppj.OccurrenceConstraintViolationV2, ocppErr.Code) - assert.Equal(t, "Field CallResult.Payload.Data.Field1 required but not found for feature DataTransfer", ocppErr.Description) + suite.Equal(ocppj.OccurrenceConstraintViolationV2, ocppErr.Code) + suite.Equal("Field CallResult.Payload.Data.Field1 required but not found for feature DataTransfer", ocppErr.Description) // Test 2: marshaling error dataTransferResponse = data.NewDataTransferResponse(data.DataTransferStatusAccepted) dataTransferResponse.Data = make(chan struct{}) dataListener.ExpectedCalls = nil dataListener.On("OnDataTransfer", mock.Anything).Return(dataTransferResponse, nil) err = suite.csms.DataTransfer(wsId, func(response *data.DataTransferResponse, err error) { - require.Nil(t, response) - require.Error(t, err) + suite.Require().Nil(response) + suite.Require().Error(err) resultChannel <- err }, "vendor1") - require.Nil(t, err) + suite.Require().Nil(err) result = <-resultChannel - require.IsType(t, &ocpp.Error{}, result) + suite.Require().IsType(&ocpp.Error{}, result) ocppErr = result.(*ocpp.Error) - assert.Equal(t, ocppj.GenericError, ocppErr.Code) - assert.Equal(t, "json: unsupported type: chan struct {}", ocppErr.Description) + suite.Equal(ocppj.GenericError, ocppErr.Code) + suite.Equal("json: unsupported type: chan struct {}", ocppErr.Description) // Test 3: no results in callback dataListener.ExpectedCalls = nil dataListener.On("OnDataTransfer", mock.Anything).Return(nil, nil) err = suite.csms.DataTransfer(wsId, func(response *data.DataTransferResponse, err error) { - require.Nil(t, response) - require.Error(t, err) + suite.Require().Nil(response) + suite.Require().Error(err) resultChannel <- err }, "vendor1") - require.Nil(t, err) + suite.Require().Nil(err) result = <-resultChannel - require.IsType(t, &ocpp.Error{}, result) + suite.Require().IsType(&ocpp.Error{}, result) ocppErr = result.(*ocpp.Error) - assert.Equal(t, ocppj.GenericError, ocppErr.Code) - assert.Equal(t, "empty response to request 1234", ocppErr.Description) + suite.Equal(ocppj.GenericError, ocppErr.Code) + suite.Equal("empty response to request 1234", ocppErr.Description) } func (suite *OcppV2TestSuite) TestCentralSystemSendResponseError() { - t := suite.T() wsId := "test_id" channel := NewMockWebSocket(wsId) var ocppErr *ocpp.Error @@ -108,19 +104,19 @@ func (suite *OcppV2TestSuite) TestCentralSystemSendResponseError() { rawMsg := args.Get(0) bytes := rawMsg.([]byte) err := suite.mockWsServer.MessageHandler(channel, bytes) - assert.Nil(t, err) + suite.Nil(err) }) suite.mockWsServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) suite.mockWsServer.On("Write", mock.AnythingOfType("string"), mock.Anything).Return(nil).Run(func(args mock.Arguments) { rawMsg := args.Get(1) bytes := rawMsg.([]byte) err := suite.mockWsClient.MessageHandler(bytes) - assert.NoError(t, err) + suite.NoError(err) }) // Run Tests suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start("someUrl") - require.Nil(t, err) + suite.Require().Nil(err) // Test 1: occurrence validation error dataTransferResponse := data.NewDataTransferResponse(data.DataTransferStatusAccepted) dataTransferResponse.Data = struct { @@ -128,34 +124,34 @@ func (suite *OcppV2TestSuite) TestCentralSystemSendResponseError() { }{Field1: ""} dataListener.On("OnDataTransfer", mock.AnythingOfType("string"), mock.Anything).Return(dataTransferResponse, nil) response, err = suite.chargingStation.DataTransfer("vendor1") - require.Nil(t, response) - require.Error(t, err) - require.IsType(t, &ocpp.Error{}, err) + suite.Require().Nil(response) + suite.Require().Error(err) + suite.Require().IsType(&ocpp.Error{}, err) ocppErr = err.(*ocpp.Error) - assert.Equal(t, ocppj.OccurrenceConstraintViolationV2, ocppErr.Code) - assert.Equal(t, "Field CallResult.Payload.Data.Field1 required but not found for feature DataTransfer", ocppErr.Description) + suite.Equal(ocppj.OccurrenceConstraintViolationV2, ocppErr.Code) + suite.Equal("Field CallResult.Payload.Data.Field1 required but not found for feature DataTransfer", ocppErr.Description) // Test 2: marshaling error dataTransferResponse = data.NewDataTransferResponse(data.DataTransferStatusAccepted) dataTransferResponse.Data = make(chan struct{}) dataListener.ExpectedCalls = nil dataListener.On("OnDataTransfer", mock.AnythingOfType("string"), mock.Anything).Return(dataTransferResponse, nil) response, err = suite.chargingStation.DataTransfer("vendor1") - require.Nil(t, response) - require.Error(t, err) - require.IsType(t, &ocpp.Error{}, err) + suite.Require().Nil(response) + suite.Require().Error(err) + suite.Require().IsType(&ocpp.Error{}, err) ocppErr = err.(*ocpp.Error) - assert.Equal(t, ocppj.GenericError, ocppErr.Code) - assert.Equal(t, "json: unsupported type: chan struct {}", ocppErr.Description) + suite.Equal(ocppj.GenericError, ocppErr.Code) + suite.Equal("json: unsupported type: chan struct {}", ocppErr.Description) // Test 3: no results in callback dataListener.ExpectedCalls = nil dataListener.On("OnDataTransfer", mock.AnythingOfType("string"), mock.Anything).Return(nil, nil) response, err = suite.chargingStation.DataTransfer("vendor1") - require.Nil(t, response) - require.Error(t, err) - require.IsType(t, &ocpp.Error{}, err) + suite.Require().Nil(response) + suite.Require().Error(err) + suite.Require().IsType(&ocpp.Error{}, err) ocppErr = err.(*ocpp.Error) - assert.Equal(t, ocppj.GenericError, ocppErr.Code) - assert.Equal(t, fmt.Sprintf("empty response to %s for request 1234", wsId), ocppErr.Description) + suite.Equal(ocppj.GenericError, ocppErr.Code) + suite.Equal(fmt.Sprintf("empty response to %s for request 1234", wsId), ocppErr.Description) } func (suite *OcppV2TestSuite) TestErrorCodes() { diff --git a/ocpp2.0.1_test/publish_firmware_status_notification_test.go b/ocpp2.0.1_test/publish_firmware_status_notification_test.go index a7e30c61..6f58f10d 100644 --- a/ocpp2.0.1_test/publish_firmware_status_notification_test.go +++ b/ocpp2.0.1_test/publish_firmware_status_notification_test.go @@ -3,16 +3,13 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/firmware" ) // Test func (suite *OcppV2TestSuite) TestPublishFirmwareStatusNotificationRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {firmware.PublishFirmwareStatusNotificationRequest{Status: firmware.PublishFirmwareStatusPublished, Location: []string{"http://someUri"}, RequestID: newInt(42)}, true}, {firmware.PublishFirmwareStatusNotificationRequest{Status: firmware.PublishFirmwareStatusPublished, Location: []string{"http://someUri"}}, true}, @@ -32,19 +29,17 @@ func (suite *OcppV2TestSuite) TestPublishFirmwareStatusNotificationRequestValida {firmware.PublishFirmwareStatusNotificationRequest{Status: firmware.PublishFirmwareStatusPublished, Location: []string{"http://someUri>512..............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................."}, RequestID: newInt(42)}, false}, //TODO: add test for empty location field with published status } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestPublishFirmwareStatusNotificationResponseValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {firmware.PublishFirmwareStatusNotificationResponse{}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestPublishFirmwareStatusNotificationE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -60,25 +55,25 @@ func (suite *OcppV2TestSuite) TestPublishFirmwareStatusNotificationE2EMocked() { handler := &MockCSMSFirmwareHandler{} handler.On("OnPublishFirmwareStatusNotification", mock.AnythingOfType("string"), mock.Anything).Return(publishFirmwareStatusNotificationResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*firmware.PublishFirmwareStatusNotificationRequest) - require.True(t, ok) - assert.Equal(t, status, request.Status) - require.Len(t, request.Location, len(location)) - assert.Equal(t, location[0], request.Location[0]) - require.NotNil(t, request.RequestID) - assert.Equal(t, *requestID, *request.RequestID) + suite.Require().True(ok) + suite.Equal(status, request.Status) + suite.Require().Len(request.Location, len(location)) + suite.Equal(location[0], request.Location[0]) + suite.Require().NotNil(request.RequestID) + suite.Equal(*requestID, *request.RequestID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) response, err := suite.chargingStation.PublishFirmwareStatusNotification(status, func(request *firmware.PublishFirmwareStatusNotificationRequest) { request.Location = location request.RequestID = requestID }) - assert.Nil(t, err) - assert.NotNil(t, response) + suite.Nil(err) + suite.NotNil(response) } func (suite *OcppV2TestSuite) TestPublishFirmwareStatusNotificationInvalidEndpoint() { diff --git a/ocpp2.0.1_test/publish_firmware_test.go b/ocpp2.0.1_test/publish_firmware_test.go index 9762c7b4..67b861ee 100644 --- a/ocpp2.0.1_test/publish_firmware_test.go +++ b/ocpp2.0.1_test/publish_firmware_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestPublishFirmwareRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {firmware.NewPublishFirmwareRequest("https://someurl", "deadbeef", 42), true}, {firmware.PublishFirmwareRequest{Location: "http://someurl", Retries: newInt(5), Checksum: "deadbeef", RequestID: 42, RetryInterval: newInt(300)}, true}, @@ -29,11 +26,10 @@ func (suite *OcppV2TestSuite) TestPublishFirmwareRequestValidation() { {firmware.PublishFirmwareRequest{Location: "http://someurl", Retries: newInt(-1), Checksum: "deadbeef", RequestID: 42, RetryInterval: newInt(300)}, false}, {firmware.PublishFirmwareRequest{Location: ">512.............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", Retries: newInt(5), Checksum: "deadbeef", RequestID: 42, RetryInterval: newInt(300)}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestPublishFirmwareResponseValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {firmware.PublishFirmwareResponse{Status: types.GenericStatusAccepted, StatusInfo: &types.StatusInfo{ReasonCode: "ok", AdditionalInfo: "someInfo"}}, true}, {firmware.PublishFirmwareResponse{Status: types.GenericStatusAccepted}, true}, @@ -41,11 +37,10 @@ func (suite *OcppV2TestSuite) TestPublishFirmwareResponseValidation() { {firmware.PublishFirmwareResponse{Status: "invalidStatus"}, false}, {firmware.PublishFirmwareResponse{Status: types.GenericStatusAccepted, StatusInfo: &types.StatusInfo{}}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestPublishFirmwareE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -67,35 +62,35 @@ func (suite *OcppV2TestSuite) TestPublishFirmwareE2EMocked() { handler := &MockChargingStationFirmwareHandler{} handler.On("OnPublishFirmware", mock.Anything).Return(publishFirmwareResponse, nil).Run(func(args mock.Arguments) { request := args.Get(0).(*firmware.PublishFirmwareRequest) - assert.Equal(t, location, request.Location) - assert.Equal(t, *retries, *request.Retries) - assert.Equal(t, checksum, request.Checksum) - assert.Equal(t, requestID, request.RequestID) - assert.Equal(t, *retryInterval, *request.RetryInterval) + suite.Equal(location, request.Location) + suite.Equal(*retries, *request.Retries) + suite.Equal(checksum, request.Checksum) + suite.Equal(requestID, request.RequestID) + suite.Equal(*retryInterval, *request.RetryInterval) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - assert.Nil(t, err) + suite.Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.PublishFirmware(wsId, func(resp *firmware.PublishFirmwareResponse, err error) { - assert.Nil(t, err) - require.NotNil(t, resp) - assert.Equal(t, publishFirmwareResponse.Status, resp.Status) - require.NotNil(t, resp.StatusInfo) - assert.Equal(t, publishFirmwareResponse.StatusInfo.ReasonCode, resp.StatusInfo.ReasonCode) - assert.Equal(t, publishFirmwareResponse.StatusInfo.AdditionalInfo, resp.StatusInfo.AdditionalInfo) + suite.Nil(err) + suite.Require().NotNil(resp) + suite.Equal(publishFirmwareResponse.Status, resp.Status) + suite.Require().NotNil(resp.StatusInfo) + suite.Equal(publishFirmwareResponse.StatusInfo.ReasonCode, resp.StatusInfo.ReasonCode) + suite.Equal(publishFirmwareResponse.StatusInfo.AdditionalInfo, resp.StatusInfo.AdditionalInfo) resultChannel <- true }, location, checksum, requestID, func(request *firmware.PublishFirmwareRequest) { request.Retries = retries request.RetryInterval = retryInterval }) - require.Nil(t, err) + suite.Require().Nil(err) if err == nil { result := <-resultChannel - assert.True(t, result) + suite.True(result) } } diff --git a/ocpp2.0.1_test/report_charging_profiles_test.go b/ocpp2.0.1_test/report_charging_profiles_test.go index a517db24..330cd7c5 100644 --- a/ocpp2.0.1_test/report_charging_profiles_test.go +++ b/ocpp2.0.1_test/report_charging_profiles_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Tests func (suite *OcppV2TestSuite) TestReportChargingProfilesRequestValidation() { - t := suite.T() chargingSchedule := types.ChargingSchedule{ ID: 1, StartSchedule: types.NewDateTime(time.Now()), @@ -39,19 +36,17 @@ func (suite *OcppV2TestSuite) TestReportChargingProfilesRequestValidation() { {smartcharging.ReportChargingProfilesRequest{RequestID: 42, ChargingLimitSource: types.ChargingLimitSourceCSO, Tbc: true, EvseID: 1, ChargingProfile: []types.ChargingProfile{ *types.NewChargingProfile(1, -1, types.ChargingProfilePurposeTxDefaultProfile, types.ChargingProfileKindAbsolute, []types.ChargingSchedule{chargingSchedule})}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestReportChargingProfilesResponseValidation() { - t := suite.T() var responseTable = []GenericTestEntry{ {smartcharging.ReportChargingProfilesResponse{}, true}, } - ExecuteGenericTestTable(t, responseTable) + ExecuteGenericTestTable(suite, responseTable) } func (suite *OcppV2TestSuite) TestReportChargingProfilesE2EMocked() { - t := suite.T() wsId := "test_id" messageId := "1234" wsUrl := "someUrl" @@ -83,38 +78,38 @@ func (suite *OcppV2TestSuite) TestReportChargingProfilesE2EMocked() { handler := &MockCSMSSmartChargingHandler{} handler.On("OnReportChargingProfiles", mock.AnythingOfType("string"), mock.Anything).Return(response, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*smartcharging.ReportChargingProfilesRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, requestID, request.RequestID) - assert.Equal(t, chargingLimitSource, request.ChargingLimitSource) - assert.Equal(t, evseID, request.EvseID) - assert.Equal(t, tbc, request.Tbc) - require.Len(t, request.ChargingProfile, 1) - assert.Equal(t, chargingProfile.ID, request.ChargingProfile[0].ID) - assert.Equal(t, chargingProfile.StackLevel, request.ChargingProfile[0].StackLevel) - assert.Equal(t, chargingProfile.ChargingProfilePurpose, request.ChargingProfile[0].ChargingProfilePurpose) - assert.Equal(t, chargingProfile.ChargingProfileKind, request.ChargingProfile[0].ChargingProfileKind) - require.Len(t, request.ChargingProfile[0].ChargingSchedule, 1) - assert.Equal(t, chargingSchedule.ID, request.ChargingProfile[0].ChargingSchedule[0].ID) - assert.Equal(t, chargingSchedule.StartSchedule.FormatTimestamp(), request.ChargingProfile[0].ChargingSchedule[0].StartSchedule.FormatTimestamp()) - assert.Equal(t, *chargingSchedule.Duration, *request.ChargingProfile[0].ChargingSchedule[0].Duration) - assert.Equal(t, chargingSchedule.ChargingRateUnit, request.ChargingProfile[0].ChargingSchedule[0].ChargingRateUnit) - assert.Equal(t, *chargingSchedule.MinChargingRate, *request.ChargingProfile[0].ChargingSchedule[0].MinChargingRate) - require.Len(t, request.ChargingProfile[0].ChargingSchedule[0].ChargingSchedulePeriod, 1) - assert.Equal(t, chargingSchedule.ChargingSchedulePeriod[0].StartPeriod, request.ChargingProfile[0].ChargingSchedule[0].ChargingSchedulePeriod[0].StartPeriod) - assert.Equal(t, chargingSchedule.ChargingSchedulePeriod[0].Limit, request.ChargingProfile[0].ChargingSchedule[0].ChargingSchedulePeriod[0].Limit) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(requestID, request.RequestID) + suite.Equal(chargingLimitSource, request.ChargingLimitSource) + suite.Equal(evseID, request.EvseID) + suite.Equal(tbc, request.Tbc) + suite.Require().Len(request.ChargingProfile, 1) + suite.Equal(chargingProfile.ID, request.ChargingProfile[0].ID) + suite.Equal(chargingProfile.StackLevel, request.ChargingProfile[0].StackLevel) + suite.Equal(chargingProfile.ChargingProfilePurpose, request.ChargingProfile[0].ChargingProfilePurpose) + suite.Equal(chargingProfile.ChargingProfileKind, request.ChargingProfile[0].ChargingProfileKind) + suite.Require().Len(request.ChargingProfile[0].ChargingSchedule, 1) + suite.Equal(chargingSchedule.ID, request.ChargingProfile[0].ChargingSchedule[0].ID) + suite.Equal(chargingSchedule.StartSchedule.FormatTimestamp(), request.ChargingProfile[0].ChargingSchedule[0].StartSchedule.FormatTimestamp()) + suite.Equal(*chargingSchedule.Duration, *request.ChargingProfile[0].ChargingSchedule[0].Duration) + suite.Equal(chargingSchedule.ChargingRateUnit, request.ChargingProfile[0].ChargingSchedule[0].ChargingRateUnit) + suite.Equal(*chargingSchedule.MinChargingRate, *request.ChargingProfile[0].ChargingSchedule[0].MinChargingRate) + suite.Require().Len(request.ChargingProfile[0].ChargingSchedule[0].ChargingSchedulePeriod, 1) + suite.Equal(chargingSchedule.ChargingSchedulePeriod[0].StartPeriod, request.ChargingProfile[0].ChargingSchedule[0].ChargingSchedulePeriod[0].StartPeriod) + suite.Equal(chargingSchedule.ChargingSchedulePeriod[0].Limit, request.ChargingProfile[0].ChargingSchedule[0].ChargingSchedulePeriod[0].Limit) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) r, err := suite.chargingStation.ReportChargingProfiles(requestID, chargingLimitSource, evseID, []types.ChargingProfile{chargingProfile}, func(request *smartcharging.ReportChargingProfilesRequest) { request.Tbc = tbc }) - require.NoError(t, err) - require.NotNil(t, r) + suite.Require().NoError(err) + suite.Require().NotNil(r) } func (suite *OcppV2TestSuite) TestReportChargingProfilesInvalidEndpoint() { diff --git a/ocpp2.0.1_test/request_start_transaction_test.go b/ocpp2.0.1_test/request_start_transaction_test.go index c778a68c..56f7dadc 100644 --- a/ocpp2.0.1_test/request_start_transaction_test.go +++ b/ocpp2.0.1_test/request_start_transaction_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/remotecontrol" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/remotecontrol" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" ) // Test func (suite *OcppV2TestSuite) TestRequestStartTransactionRequestValidation() { - t := suite.T() chargingProfile := types.ChargingProfile{ ID: 1, StackLevel: 0, @@ -44,11 +41,10 @@ func (suite *OcppV2TestSuite) TestRequestStartTransactionRequestValidation() { {remotecontrol.RequestStartTransactionRequest{EvseID: newInt(1), RemoteStartID: 42, IDToken: types.IdToken{IdToken: "1234", Type: types.IdTokenTypeKeyCode}, ChargingProfile: &types.ChargingProfile{}, GroupIdToken: &types.IdToken{IdToken: "1234", Type: types.IdTokenTypeISO15693}}, false}, {remotecontrol.RequestStartTransactionRequest{EvseID: newInt(1), RemoteStartID: 42, IDToken: types.IdToken{IdToken: "1234", Type: types.IdTokenTypeKeyCode}, ChargingProfile: &chargingProfile, GroupIdToken: &types.IdToken{IdToken: "1234", Type: "invalidGroupIdToken"}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestRequestStartTransactionConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {remotecontrol.RequestStartTransactionResponse{Status: remotecontrol.RequestStartStopStatusAccepted, TransactionID: "12345", StatusInfo: &types.StatusInfo{ReasonCode: "200"}}, true}, {remotecontrol.RequestStartTransactionResponse{Status: remotecontrol.RequestStartStopStatusAccepted, TransactionID: "12345"}, true}, @@ -59,11 +55,10 @@ func (suite *OcppV2TestSuite) TestRequestStartTransactionConfirmationValidation( {remotecontrol.RequestStartTransactionResponse{Status: remotecontrol.RequestStartStopStatusAccepted, TransactionID: ">36..................................", StatusInfo: &types.StatusInfo{ReasonCode: "200"}}, false}, {remotecontrol.RequestStartTransactionResponse{Status: remotecontrol.RequestStartStopStatusAccepted, TransactionID: "12345", StatusInfo: &types.StatusInfo{}}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestRequestStartTransactionE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -105,47 +100,47 @@ func (suite *OcppV2TestSuite) TestRequestStartTransactionE2EMocked() { handler := &MockChargingStationRemoteControlHandler{} handler.On("OnRequestStartTransaction", mock.Anything).Return(requestStartTransactionResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*remotecontrol.RequestStartTransactionRequest) - require.True(t, ok) - assert.Equal(t, *evseId, *request.EvseID) - assert.Equal(t, remoteStartID, request.RemoteStartID) - assert.Equal(t, idToken.IdToken, request.IDToken.IdToken) - assert.Equal(t, idToken.Type, request.IDToken.Type) - assert.Equal(t, chargingProfile.ID, request.ChargingProfile.ID) - assert.Equal(t, chargingProfile.ChargingProfilePurpose, request.ChargingProfile.ChargingProfilePurpose) - assert.Equal(t, chargingProfile.ChargingProfileKind, request.ChargingProfile.ChargingProfileKind) - require.Len(t, request.ChargingProfile.ChargingSchedule, len(chargingProfile.ChargingSchedule)) + suite.Require().True(ok) + suite.Equal(*evseId, *request.EvseID) + suite.Equal(remoteStartID, request.RemoteStartID) + suite.Equal(idToken.IdToken, request.IDToken.IdToken) + suite.Equal(idToken.Type, request.IDToken.Type) + suite.Equal(chargingProfile.ID, request.ChargingProfile.ID) + suite.Equal(chargingProfile.ChargingProfilePurpose, request.ChargingProfile.ChargingProfilePurpose) + suite.Equal(chargingProfile.ChargingProfileKind, request.ChargingProfile.ChargingProfileKind) + suite.Require().Len(request.ChargingProfile.ChargingSchedule, len(chargingProfile.ChargingSchedule)) s := request.ChargingProfile.ChargingSchedule[0] - assert.Equal(t, chargingProfile.ChargingSchedule[0].ID, s.ID) - assert.Equal(t, chargingProfile.ChargingSchedule[0].ChargingRateUnit, s.ChargingRateUnit) - require.Len(t, s.ChargingSchedulePeriod, len(chargingProfile.ChargingSchedule[0].ChargingSchedulePeriod)) - assert.Equal(t, chargingProfile.ChargingSchedule[0].ChargingSchedulePeriod[0].Limit, s.ChargingSchedulePeriod[0].Limit) - assert.Equal(t, chargingProfile.ChargingSchedule[0].ChargingSchedulePeriod[0].StartPeriod, s.ChargingSchedulePeriod[0].StartPeriod) - require.NotNil(t, request.GroupIdToken) - assert.Equal(t, groupIdToken.IdToken, request.GroupIdToken.IdToken) - assert.Equal(t, groupIdToken.Type, request.GroupIdToken.Type) + suite.Equal(chargingProfile.ChargingSchedule[0].ID, s.ID) + suite.Equal(chargingProfile.ChargingSchedule[0].ChargingRateUnit, s.ChargingRateUnit) + suite.Require().Len(s.ChargingSchedulePeriod, len(chargingProfile.ChargingSchedule[0].ChargingSchedulePeriod)) + suite.Equal(chargingProfile.ChargingSchedule[0].ChargingSchedulePeriod[0].Limit, s.ChargingSchedulePeriod[0].Limit) + suite.Equal(chargingProfile.ChargingSchedule[0].ChargingSchedulePeriod[0].StartPeriod, s.ChargingSchedulePeriod[0].StartPeriod) + suite.Require().NotNil(request.GroupIdToken) + suite.Equal(groupIdToken.IdToken, request.GroupIdToken.IdToken) + suite.Equal(groupIdToken.Type, request.GroupIdToken.Type) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.RequestStartTransaction(wsId, func(response *remotecontrol.RequestStartTransactionResponse, err error) { - require.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, status, response.Status) - assert.Equal(t, transactionId, response.TransactionID) - assert.Equal(t, statusInfo.ReasonCode, response.StatusInfo.ReasonCode) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Equal(status, response.Status) + suite.Equal(transactionId, response.TransactionID) + suite.Equal(statusInfo.ReasonCode, response.StatusInfo.ReasonCode) resultChannel <- true }, remoteStartID, idToken, func(request *remotecontrol.RequestStartTransactionRequest) { request.EvseID = evseId request.ChargingProfile = &chargingProfile request.GroupIdToken = &groupIdToken }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestRequestStartTransactionInvalidEndpoint() { diff --git a/ocpp2.0.1_test/request_stop_transaction_test.go b/ocpp2.0.1_test/request_stop_transaction_test.go index 889bc665..3203bd75 100644 --- a/ocpp2.0.1_test/request_stop_transaction_test.go +++ b/ocpp2.0.1_test/request_stop_transaction_test.go @@ -3,27 +3,23 @@ package ocpp2_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/remotecontrol" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/remotecontrol" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" ) // Test func (suite *OcppV2TestSuite) TestRequestStopTransactionRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {remotecontrol.RequestStopTransactionRequest{TransactionID: "12345"}, true}, {remotecontrol.RequestStopTransactionRequest{}, false}, {remotecontrol.RequestStopTransactionRequest{TransactionID: ">36.................................."}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestRequestStopTransactionConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {remotecontrol.RequestStopTransactionResponse{Status: remotecontrol.RequestStartStopStatusAccepted, StatusInfo: &types.StatusInfo{ReasonCode: "200"}}, true}, {remotecontrol.RequestStopTransactionResponse{Status: remotecontrol.RequestStartStopStatusAccepted}, true}, @@ -32,11 +28,10 @@ func (suite *OcppV2TestSuite) TestRequestStopTransactionConfirmationValidation() {remotecontrol.RequestStopTransactionResponse{Status: "invalidRequestStartStopStatus", StatusInfo: &types.StatusInfo{ReasonCode: "200"}}, false}, {remotecontrol.RequestStopTransactionResponse{Status: remotecontrol.RequestStartStopStatusAccepted, StatusInfo: &types.StatusInfo{}}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestRequestStopTransactionE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -54,26 +49,26 @@ func (suite *OcppV2TestSuite) TestRequestStopTransactionE2EMocked() { handler := &MockChargingStationRemoteControlHandler{} handler.On("OnRequestStopTransaction", mock.Anything).Return(RequestStopTransactionResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*remotecontrol.RequestStopTransactionRequest) - require.True(t, ok) - assert.Equal(t, transactionId, request.TransactionID) + suite.Require().True(ok) + suite.Equal(transactionId, request.TransactionID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.RequestStopTransaction(wsId, func(response *remotecontrol.RequestStopTransactionResponse, err error) { - require.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, status, response.Status) - assert.Equal(t, statusInfo.ReasonCode, response.StatusInfo.ReasonCode) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Equal(status, response.Status) + suite.Equal(statusInfo.ReasonCode, response.StatusInfo.ReasonCode) resultChannel <- true }, transactionId) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestRequestStopTransactionInvalidEndpoint() { diff --git a/ocpp2.0.1_test/reservation_status_update_test.go b/ocpp2.0.1_test/reservation_status_update_test.go index 950d2914..d1640713 100644 --- a/ocpp2.0.1_test/reservation_status_update_test.go +++ b/ocpp2.0.1_test/reservation_status_update_test.go @@ -3,16 +3,13 @@ package ocpp2_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/reservation" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" ) // Test func (suite *OcppV2TestSuite) TestReservationStatusUpdateRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {reservation.ReservationStatusUpdateRequest{ReservationID: 42, Status: reservation.ReservationUpdateStatusExpired}, true}, {reservation.ReservationStatusUpdateRequest{ReservationID: 42, Status: reservation.ReservationUpdateStatusRemoved}, true}, @@ -22,19 +19,17 @@ func (suite *OcppV2TestSuite) TestReservationStatusUpdateRequestValidation() { {reservation.ReservationStatusUpdateRequest{ReservationID: -1, Status: reservation.ReservationUpdateStatusExpired}, false}, {reservation.ReservationStatusUpdateRequest{ReservationID: 42, Status: "invalidReservationStatus"}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestReservationStatusUpdateConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {reservation.ReservationStatusUpdateResponse{}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestReservationStatusUpdateE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -49,19 +44,19 @@ func (suite *OcppV2TestSuite) TestReservationStatusUpdateE2EMocked() { handler := &MockCSMSReservationHandler{} handler.On("OnReservationStatusUpdate", mock.AnythingOfType("string"), mock.Anything).Return(dummyResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*reservation.ReservationStatusUpdateRequest) - require.True(t, ok) - assert.Equal(t, reservationID, request.ReservationID) - assert.Equal(t, status, request.Status) + suite.Require().True(ok) + suite.Equal(reservationID, request.ReservationID) + suite.Equal(status, request.Status) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) confirmation, err := suite.chargingStation.ReservationStatusUpdate(reservationID, status) - assert.Nil(t, err) - assert.NotNil(t, confirmation) + suite.Nil(err) + suite.NotNil(confirmation) } func (suite *OcppV2TestSuite) TestReservationStatusUpdateInvalidEndpoint() { diff --git a/ocpp2.0.1_test/reserve_now_test.go b/ocpp2.0.1_test/reserve_now_test.go index 2ab17b81..3f368fc9 100644 --- a/ocpp2.0.1_test/reserve_now_test.go +++ b/ocpp2.0.1_test/reserve_now_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/reservation" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/reservation" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" ) // Test func (suite *OcppV2TestSuite) TestReserveNowRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {reservation.ReserveNowRequest{ID: 42, ExpiryDateTime: types.NewDateTime(time.Now()), ConnectorType: reservation.ConnectorTypeCCS1, EvseID: newInt(1), IdToken: types.IdToken{IdToken: "1234", Type: types.IdTokenTypeKeyCode}, GroupIdToken: &types.IdToken{IdToken: "1234", Type: types.IdTokenTypeISO15693}}, true}, {reservation.ReserveNowRequest{ID: 42, ExpiryDateTime: types.NewDateTime(time.Now()), ConnectorType: reservation.ConnectorTypeCCS1, EvseID: newInt(1), IdToken: types.IdToken{IdToken: "1234", Type: types.IdTokenTypeKeyCode}}, true}, @@ -30,11 +27,10 @@ func (suite *OcppV2TestSuite) TestReserveNowRequestValidation() { {reservation.ReserveNowRequest{ID: 42, ExpiryDateTime: types.NewDateTime(time.Now()), ConnectorType: reservation.ConnectorTypeCCS1, EvseID: newInt(1), IdToken: types.IdToken{IdToken: "1234", Type: "invalidIdToken"}, GroupIdToken: &types.IdToken{IdToken: "1234", Type: types.IdTokenTypeISO15693}}, false}, {reservation.ReserveNowRequest{ID: 42, ExpiryDateTime: types.NewDateTime(time.Now()), ConnectorType: reservation.ConnectorTypeCCS1, EvseID: newInt(1), IdToken: types.IdToken{IdToken: "1234", Type: types.IdTokenTypeKeyCode}, GroupIdToken: &types.IdToken{IdToken: "1234", Type: "invalidIdToken"}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestReserveNowConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {reservation.ReserveNowResponse{Status: reservation.ReserveNowStatusAccepted, StatusInfo: &types.StatusInfo{ReasonCode: "200"}}, true}, {reservation.ReserveNowResponse{Status: reservation.ReserveNowStatusAccepted}, true}, @@ -42,11 +38,10 @@ func (suite *OcppV2TestSuite) TestReserveNowConfirmationValidation() { {reservation.ReserveNowResponse{Status: "invalidReserveNowStatus"}, false}, {reservation.ReserveNowResponse{Status: reservation.ReserveNowStatusAccepted, StatusInfo: &types.StatusInfo{}}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestReserveNowE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -69,38 +64,38 @@ func (suite *OcppV2TestSuite) TestReserveNowE2EMocked() { handler := &MockChargingStationReservationHandler{} handler.On("OnReserveNow", mock.Anything).Return(reserveNowResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*reservation.ReserveNowRequest) - require.True(t, ok) - assert.Equal(t, id, request.ID) - assert.Equal(t, expiryDateTime.FormatTimestamp(), request.ExpiryDateTime.FormatTimestamp()) - assert.Equal(t, connectorType, request.ConnectorType) - assert.Equal(t, *evseID, *request.EvseID) - assert.Equal(t, idToken.IdToken, request.IdToken.IdToken) - assert.Equal(t, idToken.Type, request.IdToken.Type) - require.NotNil(t, request.GroupIdToken) - assert.Equal(t, groupIdToken.IdToken, request.GroupIdToken.IdToken) - assert.Equal(t, groupIdToken.Type, request.GroupIdToken.Type) + suite.Require().True(ok) + suite.Equal(id, request.ID) + suite.Equal(expiryDateTime.FormatTimestamp(), request.ExpiryDateTime.FormatTimestamp()) + suite.Equal(connectorType, request.ConnectorType) + suite.Equal(*evseID, *request.EvseID) + suite.Equal(idToken.IdToken, request.IdToken.IdToken) + suite.Equal(idToken.Type, request.IdToken.Type) + suite.Require().NotNil(request.GroupIdToken) + suite.Equal(groupIdToken.IdToken, request.GroupIdToken.IdToken) + suite.Equal(groupIdToken.Type, request.GroupIdToken.Type) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.ReserveNow(wsId, func(resp *reservation.ReserveNowResponse, err error) { - require.Nil(t, err) - require.NotNil(t, resp) - assert.Equal(t, status, resp.Status) - assert.Equal(t, statusInfo.ReasonCode, resp.StatusInfo.ReasonCode) + suite.Require().Nil(err) + suite.Require().NotNil(resp) + suite.Equal(status, resp.Status) + suite.Equal(statusInfo.ReasonCode, resp.StatusInfo.ReasonCode) resultChannel <- true }, id, expiryDateTime, idToken, func(request *reservation.ReserveNowRequest) { request.ConnectorType = connectorType request.EvseID = evseID request.GroupIdToken = &groupIdToken }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestReserveNowInvalidEndpoint() { diff --git a/ocpp2.0.1_test/reset_test.go b/ocpp2.0.1_test/reset_test.go index b852a66c..4c41b10f 100644 --- a/ocpp2.0.1_test/reset_test.go +++ b/ocpp2.0.1_test/reset_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestResetRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {provisioning.ResetRequest{Type: provisioning.ResetTypeImmediate, EvseID: newInt(42)}, true}, {provisioning.ResetRequest{Type: provisioning.ResetTypeOnIdle, EvseID: newInt(42)}, true}, @@ -22,11 +19,10 @@ func (suite *OcppV2TestSuite) TestResetRequestValidation() { {provisioning.ResetRequest{Type: provisioning.ResetTypeImmediate, EvseID: newInt(-1)}, false}, {provisioning.ResetRequest{Type: "invalidResetType", EvseID: newInt(42)}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestResetResponseValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {provisioning.ResetResponse{Status: provisioning.ResetStatusAccepted, StatusInfo: types.NewStatusInfo("200", "")}, true}, {provisioning.ResetResponse{Status: provisioning.ResetStatusRejected, StatusInfo: types.NewStatusInfo("200", "")}, true}, @@ -36,11 +32,10 @@ func (suite *OcppV2TestSuite) TestResetResponseValidation() { {provisioning.ResetResponse{Status: provisioning.ResetStatusAccepted, StatusInfo: types.NewStatusInfo("", "")}, false}, {provisioning.ResetResponse{Status: "invalidResetStatus", StatusInfo: types.NewStatusInfo("200", "")}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestResetE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -58,30 +53,30 @@ func (suite *OcppV2TestSuite) TestResetE2EMocked() { handler := &MockChargingStationProvisioningHandler{} handler.On("OnReset", mock.Anything).Return(resetResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*provisioning.ResetRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, resetType, request.Type) - assert.Equal(t, *evseID, *request.EvseID) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(resetType, request.Type) + suite.Equal(*evseID, *request.EvseID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.Reset(wsId, func(resp *provisioning.ResetResponse, err error) { - require.Nil(t, err) - require.NotNil(t, resp) - assert.Equal(t, status, resp.Status) - assert.Equal(t, statusInfo.ReasonCode, resp.StatusInfo.ReasonCode) + suite.Require().Nil(err) + suite.Require().NotNil(resp) + suite.Equal(status, resp.Status) + suite.Equal(statusInfo.ReasonCode, resp.StatusInfo.ReasonCode) resultChannel <- true }, resetType, func(request *provisioning.ResetRequest) { request.EvseID = evseID }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestResetInvalidEndpoint() { diff --git a/ocpp2.0.1_test/security_event_notification_test.go b/ocpp2.0.1_test/security_event_notification_test.go index ab8bc4f5..ea189fd1 100644 --- a/ocpp2.0.1_test/security_event_notification_test.go +++ b/ocpp2.0.1_test/security_event_notification_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/security" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/security" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestSecurityEventNotificationRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {security.SecurityEventNotificationRequest{Type: "type1", Timestamp: types.NewDateTime(time.Now()), TechInfo: "someTechInfo"}, true}, {security.SecurityEventNotificationRequest{Type: "type1", Timestamp: types.NewDateTime(time.Now())}, true}, @@ -24,19 +21,17 @@ func (suite *OcppV2TestSuite) TestSecurityEventNotificationRequestValidation() { {security.SecurityEventNotificationRequest{Type: ">50................................................", Timestamp: types.NewDateTime(time.Now()), TechInfo: "someTechInfo"}, false}, {security.SecurityEventNotificationRequest{Type: "type1", Timestamp: types.NewDateTime(time.Now()), TechInfo: ">255............................................................................................................................................................................................................................................................"}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestSecurityEventNotificationConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {security.SecurityEventNotificationResponse{}, true}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestSecurityEventNotificationE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -52,23 +47,23 @@ func (suite *OcppV2TestSuite) TestSecurityEventNotificationE2EMocked() { handler := &MockCSMSSecurityHandler{} handler.On("OnSecurityEventNotification", mock.AnythingOfType("string"), mock.Anything).Return(securityEventNotificationResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*security.SecurityEventNotificationRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, typ, request.Type) - assert.Equal(t, timestamp.FormatTimestamp(), request.Timestamp.FormatTimestamp()) - assert.Equal(t, techInfo, request.TechInfo) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(typ, request.Type) + suite.Equal(timestamp.FormatTimestamp(), request.Timestamp.FormatTimestamp()) + suite.Equal(techInfo, request.TechInfo) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) response, err := suite.chargingStation.SecurityEventNotification(typ, timestamp, func(request *security.SecurityEventNotificationRequest) { request.TechInfo = techInfo }) - require.Nil(t, err) - require.NotNil(t, response) + suite.Require().Nil(err) + suite.Require().NotNil(response) } func (suite *OcppV2TestSuite) TestSecurityEventNotificationInvalidEndpoint() { diff --git a/ocpp2.0.1_test/send_local_list_test.go b/ocpp2.0.1_test/send_local_list_test.go index 30f13e10..78a5b244 100644 --- a/ocpp2.0.1_test/send_local_list_test.go +++ b/ocpp2.0.1_test/send_local_list_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/localauth" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/localauth" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" ) // Test func (suite *OcppV2TestSuite) TestSendLocalListRequestValidation() { - t := suite.T() authData := localauth.AuthorizationData{ IdToken: types.IdToken{ IdToken: "token1", @@ -32,11 +29,10 @@ func (suite *OcppV2TestSuite) TestSendLocalListRequestValidation() { {localauth.SendLocalListRequest{VersionNumber: -1, UpdateType: localauth.UpdateTypeDifferential, LocalAuthorizationList: []localauth.AuthorizationData{authData}}, false}, {localauth.SendLocalListRequest{VersionNumber: 42, UpdateType: "invalidUpdateType", LocalAuthorizationList: []localauth.AuthorizationData{{IdToken: types.IdToken{IdToken: "tokenWithoutType"}}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestSendLocalListResponseValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {localauth.SendLocalListResponse{Status: localauth.SendLocalListStatusAccepted, StatusInfo: types.NewStatusInfo("200", "")}, true}, {localauth.SendLocalListResponse{Status: localauth.SendLocalListStatusAccepted}, true}, @@ -44,11 +40,10 @@ func (suite *OcppV2TestSuite) TestSendLocalListResponseValidation() { {localauth.SendLocalListResponse{Status: "invalidStatus", StatusInfo: types.NewStatusInfo("200", "")}, false}, {localauth.SendLocalListResponse{Status: localauth.SendLocalListStatusAccepted, StatusInfo: types.NewStatusInfo("", "")}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestSendLocalListE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -75,39 +70,39 @@ func (suite *OcppV2TestSuite) TestSendLocalListE2EMocked() { handler := &MockChargingStationLocalAuthHandler{} handler.On("OnSendLocalList", mock.Anything).Return(sendLocalListResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*localauth.SendLocalListRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, versionNumber, request.VersionNumber) - assert.Equal(t, updateType, request.UpdateType) - require.NotNil(t, request.LocalAuthorizationList) - require.Len(t, request.LocalAuthorizationList, 1) - assert.Equal(t, authData.IdToken.IdToken, request.LocalAuthorizationList[0].IdToken.IdToken) - assert.Equal(t, authData.IdToken.Type, request.LocalAuthorizationList[0].IdToken.Type) - require.NotNil(t, request.LocalAuthorizationList[0].IdTokenInfo) - assert.Equal(t, authData.IdTokenInfo.Status, request.LocalAuthorizationList[0].IdTokenInfo.Status) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(versionNumber, request.VersionNumber) + suite.Equal(updateType, request.UpdateType) + suite.Require().NotNil(request.LocalAuthorizationList) + suite.Require().Len(request.LocalAuthorizationList, 1) + suite.Equal(authData.IdToken.IdToken, request.LocalAuthorizationList[0].IdToken.IdToken) + suite.Equal(authData.IdToken.Type, request.LocalAuthorizationList[0].IdToken.Type) + suite.Require().NotNil(request.LocalAuthorizationList[0].IdTokenInfo) + suite.Equal(authData.IdTokenInfo.Status, request.LocalAuthorizationList[0].IdTokenInfo.Status) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - assert.Nil(t, err) + suite.Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.SendLocalList(wsId, func(response *localauth.SendLocalListResponse, err error) { - assert.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, status, response.Status) - require.NotNil(t, response.StatusInfo) - assert.Equal(t, statusInfo.ReasonCode, response.StatusInfo.ReasonCode) - assert.Equal(t, statusInfo.AdditionalInfo, response.StatusInfo.AdditionalInfo) + suite.Nil(err) + suite.Require().NotNil(response) + suite.Equal(status, response.Status) + suite.Require().NotNil(response.StatusInfo) + suite.Equal(statusInfo.ReasonCode, response.StatusInfo.ReasonCode) + suite.Equal(statusInfo.AdditionalInfo, response.StatusInfo.AdditionalInfo) resultChannel <- true }, versionNumber, updateType, func(request *localauth.SendLocalListRequest) { request.LocalAuthorizationList = []localauth.AuthorizationData{authData} }) - assert.Nil(t, err) + suite.Nil(err) if err == nil { result := <-resultChannel - assert.True(t, result) + suite.True(result) } } diff --git a/ocpp2.0.1_test/set_charging_profile_test.go b/ocpp2.0.1_test/set_charging_profile_test.go index d20d21e4..a6fc9ad1 100644 --- a/ocpp2.0.1_test/set_charging_profile_test.go +++ b/ocpp2.0.1_test/set_charging_profile_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/smartcharging" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/smartcharging" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestSetChargingProfileRequestValidation() { - t := suite.T() schedule := types.NewChargingSchedule(1, types.ChargingRateUnitWatts, types.NewChargingSchedulePeriod(0, 200.0)) chargingProfile := types.NewChargingProfile( 1, @@ -28,11 +25,10 @@ func (suite *OcppV2TestSuite) TestSetChargingProfileRequestValidation() { {smartcharging.SetChargingProfileRequest{}, false}, {smartcharging.SetChargingProfileRequest{EvseID: 1, ChargingProfile: types.NewChargingProfile(1, -1, types.ChargingProfilePurposeChargingStationMaxProfile, types.ChargingProfileKindAbsolute, []types.ChargingSchedule{*schedule})}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestSetChargingProfileResponseValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {smartcharging.SetChargingProfileResponse{Status: smartcharging.ChargingProfileStatusAccepted, StatusInfo: types.NewStatusInfo("200", "")}, true}, {smartcharging.SetChargingProfileResponse{Status: smartcharging.ChargingProfileStatusAccepted}, true}, @@ -40,11 +36,10 @@ func (suite *OcppV2TestSuite) TestSetChargingProfileResponseValidation() { {smartcharging.SetChargingProfileResponse{Status: "invalidChargingProfileStatus"}, false}, {smartcharging.SetChargingProfileResponse{Status: smartcharging.ChargingProfileStatusAccepted, StatusInfo: types.NewStatusInfo("", "")}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestSetChargingProfileE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -73,41 +68,41 @@ func (suite *OcppV2TestSuite) TestSetChargingProfileE2EMocked() { handler := &MockChargingStationSmartChargingHandler{} handler.On("OnSetChargingProfile", mock.Anything).Return(setChargingProfileResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*smartcharging.SetChargingProfileRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, evseID, request.EvseID) - require.NotNil(t, request.ChargingProfile) - assert.Equal(t, profile.ID, request.ChargingProfile.ID) - assert.Equal(t, profile.StackLevel, request.ChargingProfile.StackLevel) - assert.Equal(t, profile.ChargingProfilePurpose, request.ChargingProfile.ChargingProfilePurpose) - assert.Equal(t, profile.ChargingProfileKind, request.ChargingProfile.ChargingProfileKind) - assert.Equal(t, profile.ChargingProfileKind, request.ChargingProfile.ChargingProfileKind) - assert.Equal(t, profile.ValidFrom.FormatTimestamp(), request.ChargingProfile.ValidFrom.FormatTimestamp()) - require.NotNil(t, request.ChargingProfile.ChargingSchedule) - assert.Len(t, request.ChargingProfile.ChargingSchedule, 1) - assert.Equal(t, schedule.ID, request.ChargingProfile.ChargingSchedule[0].ID) - assert.Equal(t, schedule.ChargingRateUnit, request.ChargingProfile.ChargingSchedule[0].ChargingRateUnit) - require.NotNil(t, request.ChargingProfile.ChargingSchedule[0].ChargingSchedulePeriod) - assert.Len(t, request.ChargingProfile.ChargingSchedule[0].ChargingSchedulePeriod, 1) - assert.Equal(t, period.StartPeriod, request.ChargingProfile.ChargingSchedule[0].ChargingSchedulePeriod[0].StartPeriod) - assert.Equal(t, period.Limit, request.ChargingProfile.ChargingSchedule[0].ChargingSchedulePeriod[0].Limit) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(evseID, request.EvseID) + suite.Require().NotNil(request.ChargingProfile) + suite.Equal(profile.ID, request.ChargingProfile.ID) + suite.Equal(profile.StackLevel, request.ChargingProfile.StackLevel) + suite.Equal(profile.ChargingProfilePurpose, request.ChargingProfile.ChargingProfilePurpose) + suite.Equal(profile.ChargingProfileKind, request.ChargingProfile.ChargingProfileKind) + suite.Equal(profile.ChargingProfileKind, request.ChargingProfile.ChargingProfileKind) + suite.Equal(profile.ValidFrom.FormatTimestamp(), request.ChargingProfile.ValidFrom.FormatTimestamp()) + suite.Require().NotNil(request.ChargingProfile.ChargingSchedule) + suite.Require().Len(request.ChargingProfile.ChargingSchedule, 1) + suite.Equal(schedule.ID, request.ChargingProfile.ChargingSchedule[0].ID) + suite.Equal(schedule.ChargingRateUnit, request.ChargingProfile.ChargingSchedule[0].ChargingRateUnit) + suite.Require().NotNil(request.ChargingProfile.ChargingSchedule[0].ChargingSchedulePeriod) + suite.Require().Len(request.ChargingProfile.ChargingSchedule[0].ChargingSchedulePeriod, 1) + suite.Equal(period.StartPeriod, request.ChargingProfile.ChargingSchedule[0].ChargingSchedulePeriod[0].StartPeriod) + suite.Equal(period.Limit, request.ChargingProfile.ChargingSchedule[0].ChargingSchedulePeriod[0].Limit) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.SetChargingProfile(wsId, func(confirmation *smartcharging.SetChargingProfileResponse, err error) { - require.Nil(t, err) - require.NotNil(t, confirmation) - assert.Equal(t, status, confirmation.Status) + suite.Require().Nil(err) + suite.Require().NotNil(confirmation) + suite.Equal(status, confirmation.Status) resultChannel <- true }, evseID, profile) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestSetChargingProfileInvalidEndpoint() { diff --git a/ocpp2.0.1_test/set_display_message_test.go b/ocpp2.0.1_test/set_display_message_test.go index da55bd9a..57c576c3 100644 --- a/ocpp2.0.1_test/set_display_message_test.go +++ b/ocpp2.0.1_test/set_display_message_test.go @@ -4,27 +4,23 @@ import ( "fmt" "time" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/display" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/display" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" ) // Test func (suite *OcppV2TestSuite) TestSetDisplayMessageRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {display.SetDisplayMessageRequest{Message: display.MessageInfo{ID: 42, Priority: display.MessagePriorityAlwaysFront, State: display.MessageStateIdle, StartDateTime: types.NewDateTime(time.Now()), Message: types.MessageContent{Format: types.MessageFormatUTF8, Content: "hello world"}}}, true}, {display.SetDisplayMessageRequest{}, false}, {display.SetDisplayMessageRequest{Message: display.MessageInfo{ID: 42, Priority: "invalidPriority", State: display.MessageStateIdle, StartDateTime: types.NewDateTime(time.Now()), Message: types.MessageContent{Format: types.MessageFormatUTF8, Content: "hello world"}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestSetDisplayMessageConfirmationValidation() { - t := suite.T() var responseTable = []GenericTestEntry{ {display.SetDisplayMessageResponse{Status: display.DisplayMessageStatusAccepted, StatusInfo: types.NewStatusInfo("200", "")}, true}, {display.SetDisplayMessageResponse{Status: display.DisplayMessageStatusAccepted}, true}, @@ -36,11 +32,10 @@ func (suite *OcppV2TestSuite) TestSetDisplayMessageConfirmationValidation() { {display.SetDisplayMessageResponse{Status: "invalidDisplayMessageStatus"}, false}, {display.SetDisplayMessageResponse{}, false}, } - ExecuteGenericTestTable(t, responseTable) + ExecuteGenericTestTable(suite, responseTable) } func (suite *OcppV2TestSuite) TestSetDisplayMessageE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -67,33 +62,33 @@ func (suite *OcppV2TestSuite) TestSetDisplayMessageE2EMocked() { handler := &MockChargingStationDisplayHandler{} handler.On("OnSetDisplayMessage", mock.Anything).Return(setDisplayResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*display.SetDisplayMessageRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, message.ID, request.Message.ID) - assert.Equal(t, message.Priority, request.Message.Priority) - assert.Equal(t, message.State, request.Message.State) - assertDateTimeEquality(t, message.StartDateTime, request.Message.StartDateTime) - assert.Equal(t, message.Message.Format, request.Message.Message.Format) - assert.Equal(t, message.Message.Content, request.Message.Message.Content) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(message.ID, request.Message.ID) + suite.Equal(message.Priority, request.Message.Priority) + suite.Equal(message.State, request.Message.State) + assertDateTimeEquality(suite, message.StartDateTime, request.Message.StartDateTime) + suite.Equal(message.Message.Format, request.Message.Message.Format) + suite.Equal(message.Message.Content, request.Message.Message.Content) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.SetDisplayMessage(wsId, func(response *display.SetDisplayMessageResponse, err error) { - require.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, status, response.Status) - assert.Equal(t, statusInfo.ReasonCode, response.StatusInfo.ReasonCode) - assert.Equal(t, statusInfo.AdditionalInfo, response.StatusInfo.AdditionalInfo) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Equal(status, response.Status) + suite.Equal(statusInfo.ReasonCode, response.StatusInfo.ReasonCode) + suite.Equal(statusInfo.AdditionalInfo, response.StatusInfo.AdditionalInfo) resultChannel <- true }, message) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestSetDisplayMessageInvalidEndpoint() { diff --git a/ocpp2.0.1_test/set_monitoring_base_test.go b/ocpp2.0.1_test/set_monitoring_base_test.go index 11889c9c..716880a5 100644 --- a/ocpp2.0.1_test/set_monitoring_base_test.go +++ b/ocpp2.0.1_test/set_monitoring_base_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestSetMonitoringBaseRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {diagnostics.SetMonitoringBaseRequest{MonitoringBase: diagnostics.MonitoringBaseAll}, true}, {diagnostics.SetMonitoringBaseRequest{MonitoringBase: diagnostics.MonitoringBaseFactoryDefault}, true}, @@ -21,22 +18,20 @@ func (suite *OcppV2TestSuite) TestSetMonitoringBaseRequestValidation() { {diagnostics.SetMonitoringBaseRequest{MonitoringBase: "invalidMonitoringBase"}, false}, {diagnostics.SetMonitoringBaseRequest{}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestSetMonitoringBaseConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {diagnostics.SetMonitoringBaseResponse{Status: types.GenericDeviceModelStatusAccepted, StatusInfo: types.NewStatusInfo("200", "")}, true}, {diagnostics.SetMonitoringBaseResponse{Status: types.GenericDeviceModelStatusAccepted}, true}, {diagnostics.SetMonitoringBaseResponse{Status: "invalidDeviceModelStatus"}, false}, {diagnostics.SetMonitoringBaseResponse{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestSetMonitoringBaseE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -54,28 +49,28 @@ func (suite *OcppV2TestSuite) TestSetMonitoringBaseE2EMocked() { handler := &MockChargingStationDiagnosticsHandler{} handler.On("OnSetMonitoringBase", mock.Anything).Return(setMonitoringBaseResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*diagnostics.SetMonitoringBaseRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, monitoringBase, request.MonitoringBase) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(monitoringBase, request.MonitoringBase) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.SetMonitoringBase(wsId, func(response *diagnostics.SetMonitoringBaseResponse, err error) { - require.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, status, response.Status) - assert.Equal(t, statusInfo.ReasonCode, response.StatusInfo.ReasonCode) - assert.Equal(t, statusInfo.AdditionalInfo, response.StatusInfo.AdditionalInfo) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Equal(status, response.Status) + suite.Equal(statusInfo.ReasonCode, response.StatusInfo.ReasonCode) + suite.Equal(statusInfo.AdditionalInfo, response.StatusInfo.AdditionalInfo) resultChannel <- true }, monitoringBase) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestSetMonitoringBaseInvalidEndpoint() { diff --git a/ocpp2.0.1_test/set_monitoring_level_test.go b/ocpp2.0.1_test/set_monitoring_level_test.go index bda8ea5b..53127ea1 100644 --- a/ocpp2.0.1_test/set_monitoring_level_test.go +++ b/ocpp2.0.1_test/set_monitoring_level_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestSetMonitoringLevelRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {diagnostics.SetMonitoringLevelRequest{Severity: 0}, true}, {diagnostics.SetMonitoringLevelRequest{Severity: 1}, true}, @@ -29,22 +26,20 @@ func (suite *OcppV2TestSuite) TestSetMonitoringLevelRequestValidation() { {diagnostics.SetMonitoringLevelRequest{Severity: -1}, false}, {diagnostics.SetMonitoringLevelRequest{Severity: 10}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestSetMonitoringLevelConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {diagnostics.SetMonitoringLevelResponse{Status: types.GenericDeviceModelStatusAccepted, StatusInfo: types.NewStatusInfo("200", "")}, true}, {diagnostics.SetMonitoringLevelResponse{Status: types.GenericDeviceModelStatusAccepted}, true}, {diagnostics.SetMonitoringLevelResponse{Status: "invalidDeviceModelStatus"}, false}, {diagnostics.SetMonitoringLevelResponse{}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestSetMonitoringLevelE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -62,28 +57,28 @@ func (suite *OcppV2TestSuite) TestSetMonitoringLevelE2EMocked() { handler := &MockChargingStationDiagnosticsHandler{} handler.On("OnSetMonitoringLevel", mock.Anything).Return(setMonitoringLevelResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*diagnostics.SetMonitoringLevelRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, severity, request.Severity) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(severity, request.Severity) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.SetMonitoringLevel(wsId, func(response *diagnostics.SetMonitoringLevelResponse, err error) { - require.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, status, response.Status) - assert.Equal(t, statusInfo.ReasonCode, response.StatusInfo.ReasonCode) - assert.Equal(t, statusInfo.AdditionalInfo, response.StatusInfo.AdditionalInfo) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Equal(status, response.Status) + suite.Equal(statusInfo.ReasonCode, response.StatusInfo.ReasonCode) + suite.Equal(statusInfo.AdditionalInfo, response.StatusInfo.AdditionalInfo) resultChannel <- true }, severity) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestSetMonitoringLevelInvalidEndpoint() { diff --git a/ocpp2.0.1_test/set_network_profile_test.go b/ocpp2.0.1_test/set_network_profile_test.go index 9e34cf66..5ee90345 100644 --- a/ocpp2.0.1_test/set_network_profile_test.go +++ b/ocpp2.0.1_test/set_network_profile_test.go @@ -3,12 +3,10 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test @@ -30,7 +28,7 @@ func (suite *OcppV2TestSuite) TestVPNTypeValidation() { {provisioning.VPN{Server: "someServer", User: "user1", Group: "group1", Password: "deadc0de", Key: ">255............................................................................................................................................................................................................................................................", Type: provisioning.VPNTypeIPSec}, false}, {provisioning.VPN{Server: "someServer", User: "user1", Group: "group1", Password: "deadc0de", Key: "deadbeef", Type: "invalidType"}, false}, } - ExecuteGenericTestTable(suite.T(), requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestAPNTypeValidation() { @@ -49,11 +47,10 @@ func (suite *OcppV2TestSuite) TestAPNTypeValidation() { {provisioning.APN{APN: "internet.t-mobile", APNUsername: "user1", APNPassword: "deadc0de", SimPin: newInt(-1), PreferredNetwork: ">6.....", UseOnlyPreferredNetwork: true, APNAuthentication: provisioning.APNAuthenticationAuto}, false}, {provisioning.APN{APN: "internet.t-mobile", APNUsername: "user1", APNPassword: "deadc0de", SimPin: newInt(1234), PreferredNetwork: "26201", UseOnlyPreferredNetwork: true, APNAuthentication: "invalidApnAuthentication"}, false}, } - ExecuteGenericTestTable(suite.T(), requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestSetNetworkProfileRequestValidation() { - t := suite.T() vpn := &provisioning.VPN{Server: "someServer", User: "user1", Group: "group1", Password: "deadc0de", Key: "deadbeef", Type: provisioning.VPNTypeIPSec} apn := &provisioning.APN{APN: "internet.t-mobile", APNUsername: "user1", APNPassword: "deadc0de", SimPin: newInt(1234), PreferredNetwork: "26201", UseOnlyPreferredNetwork: true, APNAuthentication: provisioning.APNAuthenticationAuto} var requestTable = []GenericTestEntry{ @@ -77,11 +74,10 @@ func (suite *OcppV2TestSuite) TestSetNetworkProfileRequestValidation() { {provisioning.SetNetworkProfileRequest{ConfigurationSlot: 2, ConnectionData: provisioning.NetworkConnectionProfile{OCPPVersion: provisioning.OCPPVersion20, OCPPTransport: provisioning.OCPPTransportJSON, CSMSUrl: "http://someUrl:8767", MessageTimeout: 30, SecurityProfile: 1, OCPPInterface: provisioning.OCPPInterfaceWired0, VPN: &provisioning.VPN{}, APN: apn}}, false}, {provisioning.SetNetworkProfileRequest{ConfigurationSlot: 2, ConnectionData: provisioning.NetworkConnectionProfile{OCPPVersion: provisioning.OCPPVersion20, OCPPTransport: provisioning.OCPPTransportJSON, CSMSUrl: "http://someUrl:8767", MessageTimeout: 30, SecurityProfile: 1, OCPPInterface: provisioning.OCPPInterfaceWired0, VPN: vpn, APN: &provisioning.APN{}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestSetNetworkProfileResponseValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {provisioning.SetNetworkProfileResponse{Status: provisioning.SetNetworkProfileStatusAccepted, StatusInfo: types.NewStatusInfo("200", "")}, true}, {provisioning.SetNetworkProfileResponse{Status: provisioning.SetNetworkProfileStatusRejected, StatusInfo: types.NewStatusInfo("200", "")}, true}, @@ -91,11 +87,10 @@ func (suite *OcppV2TestSuite) TestSetNetworkProfileResponseValidation() { {provisioning.SetNetworkProfileResponse{Status: provisioning.SetNetworkProfileStatusAccepted, StatusInfo: types.NewStatusInfo("", "")}, false}, {provisioning.SetNetworkProfileResponse{Status: "invalidSetNetworkProfileStatus", StatusInfo: types.NewStatusInfo("200", "")}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestSetNetworkProfileE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -115,48 +110,48 @@ func (suite *OcppV2TestSuite) TestSetNetworkProfileE2EMocked() { handler := &MockChargingStationProvisioningHandler{} handler.On("OnSetNetworkProfile", mock.Anything).Return(resetResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*provisioning.SetNetworkProfileRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, configurationSlot, request.ConfigurationSlot) - assert.Equal(t, data.OCPPVersion, request.ConnectionData.OCPPVersion) - assert.Equal(t, data.OCPPTransport, request.ConnectionData.OCPPTransport) - assert.Equal(t, data.CSMSUrl, request.ConnectionData.CSMSUrl) - assert.Equal(t, data.MessageTimeout, request.ConnectionData.MessageTimeout) - assert.Equal(t, data.SecurityProfile, request.ConnectionData.SecurityProfile) - assert.Equal(t, data.OCPPInterface, request.ConnectionData.OCPPInterface) - require.NotNil(t, request.ConnectionData.VPN) - assert.Equal(t, vpn.Server, request.ConnectionData.VPN.Server) - assert.Equal(t, vpn.User, request.ConnectionData.VPN.User) - assert.Equal(t, vpn.Group, request.ConnectionData.VPN.Group) - assert.Equal(t, vpn.Password, request.ConnectionData.VPN.Password) - assert.Equal(t, vpn.Key, request.ConnectionData.VPN.Key) - assert.Equal(t, vpn.Type, request.ConnectionData.VPN.Type) - require.NotNil(t, request.ConnectionData.APN) - assert.Equal(t, apn.APN, request.ConnectionData.APN.APN) - assert.Equal(t, apn.APNUsername, request.ConnectionData.APN.APNUsername) - assert.Equal(t, apn.APNPassword, request.ConnectionData.APN.APNPassword) - assert.Equal(t, *apn.SimPin, *request.ConnectionData.APN.SimPin) - assert.Equal(t, apn.PreferredNetwork, request.ConnectionData.APN.PreferredNetwork) - assert.Equal(t, apn.UseOnlyPreferredNetwork, request.ConnectionData.APN.UseOnlyPreferredNetwork) - assert.Equal(t, apn.APNAuthentication, request.ConnectionData.APN.APNAuthentication) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(configurationSlot, request.ConfigurationSlot) + suite.Equal(data.OCPPVersion, request.ConnectionData.OCPPVersion) + suite.Equal(data.OCPPTransport, request.ConnectionData.OCPPTransport) + suite.Equal(data.CSMSUrl, request.ConnectionData.CSMSUrl) + suite.Equal(data.MessageTimeout, request.ConnectionData.MessageTimeout) + suite.Equal(data.SecurityProfile, request.ConnectionData.SecurityProfile) + suite.Equal(data.OCPPInterface, request.ConnectionData.OCPPInterface) + suite.Require().NotNil(request.ConnectionData.VPN) + suite.Equal(vpn.Server, request.ConnectionData.VPN.Server) + suite.Equal(vpn.User, request.ConnectionData.VPN.User) + suite.Equal(vpn.Group, request.ConnectionData.VPN.Group) + suite.Equal(vpn.Password, request.ConnectionData.VPN.Password) + suite.Equal(vpn.Key, request.ConnectionData.VPN.Key) + suite.Equal(vpn.Type, request.ConnectionData.VPN.Type) + suite.Require().NotNil(request.ConnectionData.APN) + suite.Equal(apn.APN, request.ConnectionData.APN.APN) + suite.Equal(apn.APNUsername, request.ConnectionData.APN.APNUsername) + suite.Equal(apn.APNPassword, request.ConnectionData.APN.APNPassword) + suite.Equal(*apn.SimPin, *request.ConnectionData.APN.SimPin) + suite.Equal(apn.PreferredNetwork, request.ConnectionData.APN.PreferredNetwork) + suite.Equal(apn.UseOnlyPreferredNetwork, request.ConnectionData.APN.UseOnlyPreferredNetwork) + suite.Equal(apn.APNAuthentication, request.ConnectionData.APN.APNAuthentication) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.SetNetworkProfile(wsId, func(resp *provisioning.SetNetworkProfileResponse, err error) { - require.Nil(t, err) - require.NotNil(t, resp) - assert.Equal(t, status, resp.Status) - assert.Equal(t, statusInfo.ReasonCode, resp.StatusInfo.ReasonCode) + suite.Require().Nil(err) + suite.Require().NotNil(resp) + suite.Equal(status, resp.Status) + suite.Equal(statusInfo.ReasonCode, resp.StatusInfo.ReasonCode) resultChannel <- true }, configurationSlot, data) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestSetNetworkProfileInvalidEndpoint() { diff --git a/ocpp2.0.1_test/set_variable_monitoring_test.go b/ocpp2.0.1_test/set_variable_monitoring_test.go index c356256d..5a731f9a 100644 --- a/ocpp2.0.1_test/set_variable_monitoring_test.go +++ b/ocpp2.0.1_test/set_variable_monitoring_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/diagnostics" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/diagnostics" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" ) // Test func (suite *OcppV2TestSuite) TestSetVariableMonitoringRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {diagnostics.SetVariableMonitoringRequest{MonitoringData: []diagnostics.SetMonitoringData{{ID: newInt(2), Transaction: true, Value: 42.0, Type: diagnostics.MonitorUpperThreshold, Severity: 5, Component: types.Component{Name: "component1"}, Variable: types.Variable{Name: "variable1"}}}}, true}, {diagnostics.SetVariableMonitoringRequest{MonitoringData: []diagnostics.SetMonitoringData{{Transaction: true, Value: 42.0, Type: diagnostics.MonitorUpperThreshold, Severity: 5, Component: types.Component{Name: "component1"}, Variable: types.Variable{Name: "variable1"}}}}, true}, @@ -31,11 +28,10 @@ func (suite *OcppV2TestSuite) TestSetVariableMonitoringRequestValidation() { {diagnostics.SetVariableMonitoringRequest{MonitoringData: []diagnostics.SetMonitoringData{{ID: newInt(2), Transaction: true, Value: 42.0, Type: diagnostics.MonitorUpperThreshold, Severity: 10, Component: types.Component{Name: "component1"}, Variable: types.Variable{Name: "variable1"}}}}, false}, {diagnostics.SetVariableMonitoringRequest{MonitoringData: []diagnostics.SetMonitoringData{{ID: newInt(2), Transaction: true, Value: 42.0, Type: diagnostics.MonitorUpperThreshold, Severity: 5, Component: types.Component{}, Variable: types.Variable{}}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestSetVariableMonitoringResponseValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {diagnostics.SetVariableMonitoringResponse{MonitoringResult: []diagnostics.SetMonitoringResult{{ID: newInt(2), Status: diagnostics.SetMonitoringStatusAccepted, Type: diagnostics.MonitorUpperThreshold, Severity: 5, Component: types.Component{Name: "component1"}, Variable: types.Variable{Name: "variable1"}, StatusInfo: types.NewStatusInfo("200", "")}}}, true}, {diagnostics.SetVariableMonitoringResponse{MonitoringResult: []diagnostics.SetMonitoringResult{{ID: newInt(2), Status: diagnostics.SetMonitoringStatusAccepted, Type: diagnostics.MonitorUpperThreshold, Severity: 5, Component: types.Component{Name: "component1"}, Variable: types.Variable{Name: "variable1"}}}}, true}, @@ -54,11 +50,10 @@ func (suite *OcppV2TestSuite) TestSetVariableMonitoringResponseValidation() { {diagnostics.SetVariableMonitoringResponse{MonitoringResult: []diagnostics.SetMonitoringResult{{ID: newInt(2), Status: diagnostics.SetMonitoringStatusAccepted, Type: diagnostics.MonitorUpperThreshold, Severity: 5, Component: types.Component{Name: "component1"}, Variable: types.Variable{Name: ""}, StatusInfo: types.NewStatusInfo("200", "")}}}, false}, {diagnostics.SetVariableMonitoringResponse{MonitoringResult: []diagnostics.SetMonitoringResult{{ID: newInt(2), Status: diagnostics.SetMonitoringStatusAccepted, Type: diagnostics.MonitorUpperThreshold, Severity: 5, Component: types.Component{Name: "component1"}, Variable: types.Variable{Name: "variable1"}, StatusInfo: types.NewStatusInfo("", "")}}}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestSetVariableMonitoringE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -74,43 +69,43 @@ func (suite *OcppV2TestSuite) TestSetVariableMonitoringE2EMocked() { handler := &MockChargingStationDiagnosticsHandler{} handler.On("OnSetVariableMonitoring", mock.Anything).Return(setMonitoringVariableResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*diagnostics.SetVariableMonitoringRequest) - require.True(t, ok) - require.NotNil(t, request) - require.NotNil(t, request.MonitoringData) - require.Len(t, request.MonitoringData, 1) - assert.Equal(t, *monitoringData.ID, *request.MonitoringData[0].ID) - assert.Equal(t, monitoringData.Transaction, request.MonitoringData[0].Transaction) - assert.Equal(t, monitoringData.Value, request.MonitoringData[0].Value) - assert.Equal(t, monitoringData.Type, request.MonitoringData[0].Type) - assert.Equal(t, monitoringData.Severity, request.MonitoringData[0].Severity) - assert.Equal(t, monitoringData.Component.Name, request.MonitoringData[0].Component.Name) - assert.Equal(t, monitoringData.Variable.Name, request.MonitoringData[0].Variable.Name) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Require().NotNil(request.MonitoringData) + suite.Require().Len(request.MonitoringData, 1) + suite.Equal(*monitoringData.ID, *request.MonitoringData[0].ID) + suite.Equal(monitoringData.Transaction, request.MonitoringData[0].Transaction) + suite.Equal(monitoringData.Value, request.MonitoringData[0].Value) + suite.Equal(monitoringData.Type, request.MonitoringData[0].Type) + suite.Equal(monitoringData.Severity, request.MonitoringData[0].Severity) + suite.Equal(monitoringData.Component.Name, request.MonitoringData[0].Component.Name) + suite.Equal(monitoringData.Variable.Name, request.MonitoringData[0].Variable.Name) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.SetVariableMonitoring(wsId, func(response *diagnostics.SetVariableMonitoringResponse, err error) { - require.Nil(t, err) - require.NotNil(t, response) - require.NotNil(t, response.MonitoringResult) - require.Len(t, response.MonitoringResult, 1) - assert.Equal(t, *monitoringResult.ID, *response.MonitoringResult[0].ID) - assert.Equal(t, monitoringResult.Status, response.MonitoringResult[0].Status) - assert.Equal(t, monitoringResult.Type, response.MonitoringResult[0].Type) - assert.Equal(t, monitoringResult.Severity, response.MonitoringResult[0].Severity) - assert.Equal(t, monitoringResult.Component.Name, response.MonitoringResult[0].Component.Name) - assert.Equal(t, monitoringResult.Variable, response.MonitoringResult[0].Variable) - require.NotNil(t, response.MonitoringResult[0].StatusInfo) - assert.Equal(t, monitoringResult.StatusInfo.ReasonCode, response.MonitoringResult[0].StatusInfo.ReasonCode) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Require().NotNil(response.MonitoringResult) + suite.Require().Len(response.MonitoringResult, 1) + suite.Equal(*monitoringResult.ID, *response.MonitoringResult[0].ID) + suite.Equal(monitoringResult.Status, response.MonitoringResult[0].Status) + suite.Equal(monitoringResult.Type, response.MonitoringResult[0].Type) + suite.Equal(monitoringResult.Severity, response.MonitoringResult[0].Severity) + suite.Equal(monitoringResult.Component.Name, response.MonitoringResult[0].Component.Name) + suite.Equal(monitoringResult.Variable, response.MonitoringResult[0].Variable) + suite.Require().NotNil(response.MonitoringResult[0].StatusInfo) + suite.Equal(monitoringResult.StatusInfo.ReasonCode, response.MonitoringResult[0].StatusInfo.ReasonCode) resultChannel <- true }, []diagnostics.SetMonitoringData{monitoringData}) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestSetVariableMonitoringInvalidEndpoint() { diff --git a/ocpp2.0.1_test/set_variables_test.go b/ocpp2.0.1_test/set_variables_test.go index 8149bd19..aac4f315 100644 --- a/ocpp2.0.1_test/set_variables_test.go +++ b/ocpp2.0.1_test/set_variables_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/provisioning" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/provisioning" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestSetVariablesRequestValidation() { - t := suite.T() component := types.Component{Name: "component1", Instance: "instance1", EVSE: &types.EVSE{ID: 2, ConnectorID: newInt(2)}} variable := types.Variable{Name: "variable1", Instance: "instance1"} @@ -33,11 +30,10 @@ func (suite *OcppV2TestSuite) TestSetVariablesRequestValidation() { {provisioning.SetVariablesRequest{SetVariableData: []provisioning.SetVariableData{{AttributeType: types.AttributeTarget, AttributeValue: "dummyValue", Component: component}}}, false}, {provisioning.SetVariablesRequest{SetVariableData: []provisioning.SetVariableData{{AttributeType: types.AttributeTarget, AttributeValue: "dummyValue", Component: types.Component{Name: "component1", EVSE: &types.EVSE{ID: -1}}, Variable: variable}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestSetVariablesResponseValidation() { - t := suite.T() component := types.Component{Name: "component1", Instance: "instance1", EVSE: &types.EVSE{ID: 2, ConnectorID: newInt(2)}} variable := types.Variable{Name: "variable1", Instance: "instance1"} var confirmationTable = []GenericTestEntry{ @@ -55,11 +51,10 @@ func (suite *OcppV2TestSuite) TestSetVariablesResponseValidation() { {provisioning.SetVariablesResponse{SetVariableResult: []provisioning.SetVariableResult{{AttributeType: types.AttributeTarget, AttributeStatus: provisioning.SetVariableStatusAccepted, Component: component, Variable: types.Variable{}}}}, false}, {provisioning.SetVariablesResponse{SetVariableResult: []provisioning.SetVariableResult{{AttributeType: types.AttributeTarget, AttributeStatus: provisioning.SetVariableStatusAccepted, Component: component, Variable: variable, StatusInfo: types.NewStatusInfo("", "")}}}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestSetVariablesE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -90,44 +85,44 @@ func (suite *OcppV2TestSuite) TestSetVariablesE2EMocked() { handler := &MockChargingStationProvisioningHandler{} handler.On("OnSetVariables", mock.Anything).Return(getVariablesResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*provisioning.SetVariablesRequest) - require.True(t, ok) - require.NotNil(t, request) - require.Len(t, request.SetVariableData, 1) - assert.Equal(t, variableData.AttributeType, request.SetVariableData[0].AttributeType) - assert.Equal(t, variableData.AttributeValue, request.SetVariableData[0].AttributeValue) - assert.Equal(t, variableData.Component.Name, request.SetVariableData[0].Component.Name) - assert.Equal(t, variableData.Component.Instance, request.SetVariableData[0].Component.Instance) - assert.Equal(t, variableData.Component.EVSE.ID, request.SetVariableData[0].Component.EVSE.ID) - assert.Equal(t, *variableData.Component.EVSE.ConnectorID, *request.SetVariableData[0].Component.EVSE.ConnectorID) - assert.Equal(t, variableData.Variable.Name, request.SetVariableData[0].Variable.Name) - assert.Equal(t, variableData.Variable.Instance, request.SetVariableData[0].Variable.Instance) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Require().Len(request.SetVariableData, 1) + suite.Equal(variableData.AttributeType, request.SetVariableData[0].AttributeType) + suite.Equal(variableData.AttributeValue, request.SetVariableData[0].AttributeValue) + suite.Equal(variableData.Component.Name, request.SetVariableData[0].Component.Name) + suite.Equal(variableData.Component.Instance, request.SetVariableData[0].Component.Instance) + suite.Equal(variableData.Component.EVSE.ID, request.SetVariableData[0].Component.EVSE.ID) + suite.Equal(*variableData.Component.EVSE.ConnectorID, *request.SetVariableData[0].Component.EVSE.ConnectorID) + suite.Equal(variableData.Variable.Name, request.SetVariableData[0].Variable.Name) + suite.Equal(variableData.Variable.Instance, request.SetVariableData[0].Variable.Instance) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.SetVariables(wsId, func(response *provisioning.SetVariablesResponse, err error) { - require.Nil(t, err) - require.NotNil(t, response) - require.Len(t, response.SetVariableResult, 1) - assert.Equal(t, variableResult.AttributeStatus, response.SetVariableResult[0].AttributeStatus) - assert.Equal(t, variableResult.AttributeType, response.SetVariableResult[0].AttributeType) - assert.Equal(t, variableResult.Component.Name, response.SetVariableResult[0].Component.Name) - assert.Equal(t, variableResult.Component.Instance, response.SetVariableResult[0].Component.Instance) - assert.Equal(t, variableResult.Component.EVSE.ID, response.SetVariableResult[0].Component.EVSE.ID) - assert.Equal(t, *variableResult.Component.EVSE.ConnectorID, *response.SetVariableResult[0].Component.EVSE.ConnectorID) - assert.Equal(t, variableResult.Variable.Name, response.SetVariableResult[0].Variable.Name) - assert.Equal(t, variableResult.Variable.Instance, response.SetVariableResult[0].Variable.Instance) - require.NotNil(t, response.SetVariableResult[0].StatusInfo) - assert.Equal(t, statusInfo.ReasonCode, response.SetVariableResult[0].StatusInfo.ReasonCode) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Require().Len(response.SetVariableResult, 1) + suite.Equal(variableResult.AttributeStatus, response.SetVariableResult[0].AttributeStatus) + suite.Equal(variableResult.AttributeType, response.SetVariableResult[0].AttributeType) + suite.Equal(variableResult.Component.Name, response.SetVariableResult[0].Component.Name) + suite.Equal(variableResult.Component.Instance, response.SetVariableResult[0].Component.Instance) + suite.Equal(variableResult.Component.EVSE.ID, response.SetVariableResult[0].Component.EVSE.ID) + suite.Equal(*variableResult.Component.EVSE.ConnectorID, *response.SetVariableResult[0].Component.EVSE.ConnectorID) + suite.Equal(variableResult.Variable.Name, response.SetVariableResult[0].Variable.Name) + suite.Equal(variableResult.Variable.Instance, response.SetVariableResult[0].Variable.Instance) + suite.Require().NotNil(response.SetVariableResult[0].StatusInfo) + suite.Equal(statusInfo.ReasonCode, response.SetVariableResult[0].StatusInfo.ReasonCode) resultChannel <- true }, []provisioning.SetVariableData{variableData}) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestSetVariablesInvalidEndpoint() { diff --git a/ocpp2.0.1_test/sign_certificate_test.go b/ocpp2.0.1_test/sign_certificate_test.go index 31c2b9be..f61bf59d 100644 --- a/ocpp2.0.1_test/sign_certificate_test.go +++ b/ocpp2.0.1_test/sign_certificate_test.go @@ -3,12 +3,10 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/security" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/security" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test @@ -20,11 +18,10 @@ func (suite *OcppV2TestSuite) TestSignCertificateRequestValidation() { {security.SignCertificateRequest{}, false}, {security.SignCertificateRequest{CSR: "deadc0de", CertificateType: "invalidType"}, false}, } - ExecuteGenericTestTable(suite.T(), requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestSignCertificateConfirmationValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {security.SignCertificateResponse{Status: types.GenericStatusAccepted, StatusInfo: types.NewStatusInfo("200", "")}, true}, {security.SignCertificateResponse{Status: types.GenericStatusAccepted}, true}, @@ -32,11 +29,10 @@ func (suite *OcppV2TestSuite) TestSignCertificateConfirmationValidation() { {security.SignCertificateResponse{Status: types.GenericStatusAccepted, StatusInfo: types.NewStatusInfo("", "")}, false}, {security.SignCertificateResponse{Status: "invalidStatus", StatusInfo: types.NewStatusInfo("200", "")}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestSignCertificateE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -55,25 +51,25 @@ func (suite *OcppV2TestSuite) TestSignCertificateE2EMocked() { handler := &MockCSMSSecurityHandler{} handler.On("OnSignCertificate", mock.AnythingOfType("string"), mock.Anything).Return(signCertificateResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*security.SignCertificateRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, csr, request.CSR) - assert.Equal(t, certificateType, request.CertificateType) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(csr, request.CSR) + suite.Equal(certificateType, request.CertificateType) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) response, err := suite.chargingStation.SignCertificate(csr, func(request *security.SignCertificateRequest) { request.CertificateType = certificateType }) - require.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, status, response.Status) - assert.Equal(t, statusInfo.ReasonCode, response.StatusInfo.ReasonCode) - assert.Equal(t, statusInfo.AdditionalInfo, response.StatusInfo.AdditionalInfo) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Equal(status, response.Status) + suite.Equal(statusInfo.ReasonCode, response.StatusInfo.ReasonCode) + suite.Equal(statusInfo.AdditionalInfo, response.StatusInfo.AdditionalInfo) } func (suite *OcppV2TestSuite) TestSignCertificateInvalidEndpoint() { diff --git a/ocpp2.0.1_test/status_notification_test.go b/ocpp2.0.1_test/status_notification_test.go index dee08c0e..b4e4f5ea 100644 --- a/ocpp2.0.1_test/status_notification_test.go +++ b/ocpp2.0.1_test/status_notification_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/availability" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/availability" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestStatusNotificationRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {availability.StatusNotificationRequest{Timestamp: types.NewDateTime(time.Now()), ConnectorStatus: availability.ConnectorStatusAvailable, EvseID: 1, ConnectorID: 1}, true}, {availability.StatusNotificationRequest{Timestamp: types.NewDateTime(time.Now()), ConnectorStatus: availability.ConnectorStatusAvailable, EvseID: 1}, true}, @@ -26,19 +23,17 @@ func (suite *OcppV2TestSuite) TestStatusNotificationRequestValidation() { {availability.StatusNotificationRequest{Timestamp: types.NewDateTime(time.Now()), ConnectorStatus: availability.ConnectorStatusAvailable, EvseID: -1, ConnectorID: 1}, false}, {availability.StatusNotificationRequest{Timestamp: types.NewDateTime(time.Now()), ConnectorStatus: availability.ConnectorStatusAvailable, EvseID: 1, ConnectorID: -1}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestStatusNotificationResponseValidation() { - t := suite.T() var responseTable = []GenericTestEntry{ {availability.StatusNotificationResponse{}, true}, } - ExecuteGenericTestTable(t, responseTable) + ExecuteGenericTestTable(suite, responseTable) } func (suite *OcppV2TestSuite) TestStatusNotificationE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -56,22 +51,22 @@ func (suite *OcppV2TestSuite) TestStatusNotificationE2EMocked() { handler := &MockCSMSAvailabilityHandler{} handler.On("OnStatusNotification", mock.AnythingOfType("string"), mock.Anything).Return(statusNotificationResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*availability.StatusNotificationRequest) - require.True(t, ok) - require.NotNil(t, request) - assertDateTimeEquality(t, timestamp, request.Timestamp) - assert.Equal(t, status, request.ConnectorStatus) - assert.Equal(t, evseID, request.EvseID) - assert.Equal(t, connectorID, request.ConnectorID) + suite.Require().True(ok) + suite.Require().NotNil(request) + assertDateTimeEquality(suite, timestamp, request.Timestamp) + suite.Equal(status, request.ConnectorStatus) + suite.Equal(evseID, request.EvseID) + suite.Equal(connectorID, request.ConnectorID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - assert.Nil(t, err) + suite.Nil(err) response, err := suite.chargingStation.StatusNotification(timestamp, status, evseID, connectorID) - assert.Nil(t, err) - assert.NotNil(t, response) + suite.Nil(err) + suite.NotNil(response) } func (suite *OcppV2TestSuite) TestStatusNotificationInvalidEndpoint() { diff --git a/ocpp2.0.1_test/transaction_event_test.go b/ocpp2.0.1_test/transaction_event_test.go index 0042c39f..3b90a929 100644 --- a/ocpp2.0.1_test/transaction_event_test.go +++ b/ocpp2.0.1_test/transaction_event_test.go @@ -4,12 +4,10 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/transactions" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/transactions" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test @@ -25,11 +23,10 @@ func (suite *OcppV2TestSuite) TestTransactionInfoValidation() { {transactions.Transaction{TransactionID: "42", ChargingState: "invalidChargingState", TimeSpentCharging: newInt(100), StoppedReason: transactions.ReasonLocal, RemoteStartID: newInt(7)}, false}, {transactions.Transaction{TransactionID: "42", ChargingState: transactions.ChargingStateSuspendedEV, TimeSpentCharging: newInt(100), StoppedReason: "invalidReason", RemoteStartID: newInt(7)}, false}, } - ExecuteGenericTestTable(suite.T(), requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestTransactionEventRequestValidation() { - t := suite.T() transactionInfo := transactions.Transaction{TransactionID: "42"} idToken := types.IdToken{IdToken: "1234", Type: types.IdTokenTypeKeyCode} meterValue := types.MeterValue{Timestamp: *types.NewDateTime(time.Now()), SampledValue: []types.SampledValue{{Value: 64.0}}} @@ -60,11 +57,10 @@ func (suite *OcppV2TestSuite) TestTransactionEventRequestValidation() { {transactions.TransactionEventRequest{EventType: transactions.TransactionEventStarted, Timestamp: types.NewDateTime(time.Now()), TriggerReason: transactions.TriggerReasonAuthorized, SequenceNo: 1, Offline: true, NumberOfPhasesUsed: newInt(3), CableMaxCurrent: newInt(20), ReservationID: newInt(42), TransactionInfo: transactionInfo, IDToken: &idToken, Evse: &types.EVSE{ID: -1}, MeterValue: []types.MeterValue{meterValue}}, false}, {transactions.TransactionEventRequest{EventType: transactions.TransactionEventStarted, Timestamp: types.NewDateTime(time.Now()), TriggerReason: transactions.TriggerReasonAuthorized, SequenceNo: 1, Offline: true, NumberOfPhasesUsed: newInt(3), CableMaxCurrent: newInt(20), ReservationID: newInt(42), TransactionInfo: transactionInfo, IDToken: &idToken, Evse: &types.EVSE{ID: 1}, MeterValue: []types.MeterValue{{}}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestTransactionEventResponseValidation() { - t := suite.T() messageContent := types.MessageContent{Format: types.MessageFormatUTF8, Content: "dummyContent"} var responseTable = []GenericTestEntry{ {transactions.TransactionEventResponse{TotalCost: newFloat(8.42), ChargingPriority: newInt(2), IDTokenInfo: types.NewIdTokenInfo(types.AuthorizationStatusAccepted), UpdatedPersonalMessage: &messageContent}, true}, @@ -78,11 +74,10 @@ func (suite *OcppV2TestSuite) TestTransactionEventResponseValidation() { {transactions.TransactionEventResponse{TotalCost: newFloat(8.42), ChargingPriority: newInt(2), IDTokenInfo: types.NewIdTokenInfo("invalidAuthorizationStatus"), UpdatedPersonalMessage: &messageContent}, false}, {transactions.TransactionEventResponse{TotalCost: newFloat(8.42), ChargingPriority: newInt(2), IDTokenInfo: types.NewIdTokenInfo(types.AuthorizationStatusAccepted), UpdatedPersonalMessage: &types.MessageContent{}}, false}, } - ExecuteGenericTestTable(t, responseTable) + ExecuteGenericTestTable(suite, responseTable) } func (suite *OcppV2TestSuite) TestTransactionEventE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -116,38 +111,38 @@ func (suite *OcppV2TestSuite) TestTransactionEventE2EMocked() { handler := &MockCSMSTransactionsHandler{} handler.On("OnTransactionEvent", mock.AnythingOfType("string"), mock.Anything).Return(transactionResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(1).(*transactions.TransactionEventRequest) - require.True(t, ok) - require.NotNil(t, request) - assert.Equal(t, eventType, request.EventType) - assertDateTimeEquality(t, timestamp, request.Timestamp) - assert.Equal(t, triggerReason, request.TriggerReason) - assert.Equal(t, seqNo, request.SequenceNo) - assert.Equal(t, offline, request.Offline) - assert.Equal(t, *phases, *request.NumberOfPhasesUsed) - assert.Equal(t, *cableMaxCurrent, *request.CableMaxCurrent) - assert.Equal(t, *reservationID, *request.ReservationID) - assert.Equal(t, eventType, request.EventType) - assert.Equal(t, info.TransactionID, request.TransactionInfo.TransactionID) - assert.Equal(t, info.StoppedReason, request.TransactionInfo.StoppedReason) - assert.Equal(t, info.ChargingState, request.TransactionInfo.ChargingState) - assert.Equal(t, *info.TimeSpentCharging, *request.TransactionInfo.TimeSpentCharging) - assert.Equal(t, *info.RemoteStartID, *request.TransactionInfo.RemoteStartID) - require.NotNil(t, request.IDToken) - assert.Equal(t, idToken.IdToken, request.IDToken.IdToken) - assert.Equal(t, idToken.Type, request.IDToken.Type) - require.NotNil(t, request.Evse) - assert.Equal(t, evse.ID, request.Evse.ID) - require.Len(t, request.MeterValue, 1) - assertDateTimeEquality(t, &meterValue.Timestamp, &request.MeterValue[0].Timestamp) - require.Len(t, request.MeterValue[0].SampledValue, 1) - assert.Equal(t, meterValue.SampledValue[0].Value, request.MeterValue[0].SampledValue[0].Value) + suite.Require().True(ok) + suite.Require().NotNil(request) + suite.Equal(eventType, request.EventType) + assertDateTimeEquality(suite, timestamp, request.Timestamp) + suite.Equal(triggerReason, request.TriggerReason) + suite.Equal(seqNo, request.SequenceNo) + suite.Equal(offline, request.Offline) + suite.Equal(*phases, *request.NumberOfPhasesUsed) + suite.Equal(*cableMaxCurrent, *request.CableMaxCurrent) + suite.Equal(*reservationID, *request.ReservationID) + suite.Equal(eventType, request.EventType) + suite.Equal(info.TransactionID, request.TransactionInfo.TransactionID) + suite.Equal(info.StoppedReason, request.TransactionInfo.StoppedReason) + suite.Equal(info.ChargingState, request.TransactionInfo.ChargingState) + suite.Equal(*info.TimeSpentCharging, *request.TransactionInfo.TimeSpentCharging) + suite.Equal(*info.RemoteStartID, *request.TransactionInfo.RemoteStartID) + suite.Require().NotNil(request.IDToken) + suite.Equal(idToken.IdToken, request.IDToken.IdToken) + suite.Equal(idToken.Type, request.IDToken.Type) + suite.Require().NotNil(request.Evse) + suite.Equal(evse.ID, request.Evse.ID) + suite.Require().Len(request.MeterValue, 1) + assertDateTimeEquality(suite, &meterValue.Timestamp, &request.MeterValue[0].Timestamp) + suite.Require().Len(request.MeterValue[0].SampledValue, 1) + suite.Equal(meterValue.SampledValue[0].Value, request.MeterValue[0].SampledValue[0].Value) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.NoError(t, err) + suite.Require().NoError(err) response, err := suite.chargingStation.TransactionEvent(eventType, timestamp, triggerReason, seqNo, info, func(request *transactions.TransactionEventRequest) { request.MeterValue = []types.MeterValue{meterValue} request.Evse = &evse @@ -157,15 +152,15 @@ func (suite *OcppV2TestSuite) TestTransactionEventE2EMocked() { request.ReservationID = reservationID request.Offline = offline }) - require.NoError(t, err) - require.NotNil(t, response) - assert.Equal(t, *totalCost, *response.TotalCost) - assert.Equal(t, *chargingPriority, *response.ChargingPriority) - require.NotNil(t, response.IDTokenInfo) - assert.Equal(t, idTokenInfo.Status, response.IDTokenInfo.Status) - require.NotNil(t, response.UpdatedPersonalMessage) - assert.Equal(t, messageContent.Format, response.UpdatedPersonalMessage.Format) - assert.Equal(t, messageContent.Content, response.UpdatedPersonalMessage.Content) + suite.Require().NoError(err) + suite.Require().NotNil(response) + suite.Equal(*totalCost, *response.TotalCost) + suite.Equal(*chargingPriority, *response.ChargingPriority) + suite.Require().NotNil(response.IDTokenInfo) + suite.Equal(idTokenInfo.Status, response.IDTokenInfo.Status) + suite.Require().NotNil(response.UpdatedPersonalMessage) + suite.Equal(messageContent.Format, response.UpdatedPersonalMessage.Format) + suite.Equal(messageContent.Content, response.UpdatedPersonalMessage.Content) } func (suite *OcppV2TestSuite) TestTransactionEventInvalidEndpoint() { diff --git a/ocpp2.0.1_test/trigger_message_test.go b/ocpp2.0.1_test/trigger_message_test.go index ce43fe0f..230b4487 100644 --- a/ocpp2.0.1_test/trigger_message_test.go +++ b/ocpp2.0.1_test/trigger_message_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/remotecontrol" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/remotecontrol" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" ) // Test func (suite *OcppV2TestSuite) TestTriggerMessageRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {remotecontrol.TriggerMessageRequest{RequestedMessage: remotecontrol.MessageTriggerStatusNotification, Evse: &types.EVSE{ID: 1}}, true}, {remotecontrol.TriggerMessageRequest{RequestedMessage: remotecontrol.MessageTriggerStatusNotification}, true}, @@ -21,11 +18,10 @@ func (suite *OcppV2TestSuite) TestTriggerMessageRequestValidation() { {remotecontrol.TriggerMessageRequest{RequestedMessage: "invalidMessageTrigger", Evse: &types.EVSE{ID: 1}}, false}, {remotecontrol.TriggerMessageRequest{RequestedMessage: remotecontrol.MessageTriggerStatusNotification, Evse: &types.EVSE{ID: -1}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestTriggerMessageResponseValidation() { - t := suite.T() var responseTable = []GenericTestEntry{ {remotecontrol.TriggerMessageResponse{Status: remotecontrol.TriggerMessageStatusAccepted, StatusInfo: &types.StatusInfo{ReasonCode: "200"}}, true}, {remotecontrol.TriggerMessageResponse{Status: remotecontrol.TriggerMessageStatusAccepted}, true}, @@ -33,11 +29,10 @@ func (suite *OcppV2TestSuite) TestTriggerMessageResponseValidation() { {remotecontrol.TriggerMessageResponse{Status: "invalidTriggerMessageStatus", StatusInfo: &types.StatusInfo{ReasonCode: "200"}}, false}, {remotecontrol.TriggerMessageResponse{Status: remotecontrol.TriggerMessageStatusAccepted, StatusInfo: &types.StatusInfo{}}, false}, } - ExecuteGenericTestTable(t, responseTable) + ExecuteGenericTestTable(suite, responseTable) } func (suite *OcppV2TestSuite) TestTriggerMessageE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -56,30 +51,30 @@ func (suite *OcppV2TestSuite) TestTriggerMessageE2EMocked() { handler := &MockChargingStationRemoteControlHandler{} handler.On("OnTriggerMessage", mock.Anything).Return(triggerMessageResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*remotecontrol.TriggerMessageRequest) - require.True(t, ok) - assert.Equal(t, requestedMessage, request.RequestedMessage) - require.NotNil(t, request.Evse) - assert.Equal(t, evse.ID, request.Evse.ID) + suite.Require().True(ok) + suite.Equal(requestedMessage, request.RequestedMessage) + suite.Require().NotNil(request.Evse) + suite.Equal(evse.ID, request.Evse.ID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.TriggerMessage(wsId, func(response *remotecontrol.TriggerMessageResponse, err error) { - require.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, status, response.Status) - assert.Equal(t, statusInfo.ReasonCode, response.StatusInfo.ReasonCode) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Equal(status, response.Status) + suite.Equal(statusInfo.ReasonCode, response.StatusInfo.ReasonCode) resultChannel <- true }, requestedMessage, func(request *remotecontrol.TriggerMessageRequest) { request.Evse = &evse }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestTriggerMessageInvalidEndpoint() { diff --git a/ocpp2.0.1_test/unlock_connector_test.go b/ocpp2.0.1_test/unlock_connector_test.go index 1be9e26d..3c573bea 100644 --- a/ocpp2.0.1_test/unlock_connector_test.go +++ b/ocpp2.0.1_test/unlock_connector_test.go @@ -3,17 +3,14 @@ package ocpp2_test import ( "fmt" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/remotecontrol" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/remotecontrol" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" ) // Test func (suite *OcppV2TestSuite) TestUnlockConnectorRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {remotecontrol.UnlockConnectorRequest{EvseID: 2, ConnectorID: 1}, true}, {remotecontrol.UnlockConnectorRequest{EvseID: 2}, true}, @@ -21,11 +18,10 @@ func (suite *OcppV2TestSuite) TestUnlockConnectorRequestValidation() { {remotecontrol.UnlockConnectorRequest{EvseID: -1, ConnectorID: 1}, false}, {remotecontrol.UnlockConnectorRequest{EvseID: 2, ConnectorID: -1}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestUnlockConnectorResponseValidation() { - t := suite.T() var responseTable = []GenericTestEntry{ {remotecontrol.UnlockConnectorResponse{Status: remotecontrol.UnlockStatusUnlocked, StatusInfo: &types.StatusInfo{ReasonCode: "200"}}, true}, {remotecontrol.UnlockConnectorResponse{Status: remotecontrol.UnlockStatusUnlocked}, true}, @@ -33,11 +29,10 @@ func (suite *OcppV2TestSuite) TestUnlockConnectorResponseValidation() { {remotecontrol.UnlockConnectorResponse{Status: "invalidUnlockStatus", StatusInfo: &types.StatusInfo{ReasonCode: "200"}}, false}, {remotecontrol.UnlockConnectorResponse{Status: remotecontrol.UnlockStatusUnlocked, StatusInfo: &types.StatusInfo{}}, false}, } - ExecuteGenericTestTable(t, responseTable) + ExecuteGenericTestTable(suite, responseTable) } func (suite *OcppV2TestSuite) TestUnlockConnectorE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -56,27 +51,27 @@ func (suite *OcppV2TestSuite) TestUnlockConnectorE2EMocked() { handler := &MockChargingStationRemoteControlHandler{} handler.On("OnUnlockConnector", mock.Anything).Return(triggerMessageResponse, nil).Run(func(args mock.Arguments) { request, ok := args.Get(0).(*remotecontrol.UnlockConnectorRequest) - require.True(t, ok) - assert.Equal(t, evseID, request.EvseID) - assert.Equal(t, connectorID, request.ConnectorID) + suite.Require().True(ok) + suite.Equal(evseID, request.EvseID) + suite.Equal(connectorID, request.ConnectorID) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - require.Nil(t, err) + suite.Require().Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.UnlockConnector(wsId, func(response *remotecontrol.UnlockConnectorResponse, err error) { - require.Nil(t, err) - require.NotNil(t, response) - assert.Equal(t, status, response.Status) - assert.Equal(t, statusInfo.ReasonCode, response.StatusInfo.ReasonCode) + suite.Require().Nil(err) + suite.Require().NotNil(response) + suite.Equal(status, response.Status) + suite.Equal(statusInfo.ReasonCode, response.StatusInfo.ReasonCode) resultChannel <- true }, evseID, connectorID) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestUnlockConnectorInvalidEndpoint() { diff --git a/ocpp2.0.1_test/unpublish_firmware_test.go b/ocpp2.0.1_test/unpublish_firmware_test.go index bbe33b63..97a9caaa 100644 --- a/ocpp2.0.1_test/unpublish_firmware_test.go +++ b/ocpp2.0.1_test/unpublish_firmware_test.go @@ -3,26 +3,22 @@ package ocpp2_test import ( "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/firmware" ) // Test func (suite *OcppV2TestSuite) TestUnpublishFirmwareRequestValidation() { - t := suite.T() var requestTable = []GenericTestEntry{ {firmware.UnpublishFirmwareRequest{Checksum: "deadc0de"}, true}, {firmware.UnpublishFirmwareRequest{}, false}, {firmware.UnpublishFirmwareRequest{Checksum: ">32.............................."}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestUnpublishFirmwareResponseValidation() { - t := suite.T() var confirmationTable = []GenericTestEntry{ {firmware.UnpublishFirmwareResponse{Status: firmware.UnpublishFirmwareStatusUnpublished}, true}, {firmware.UnpublishFirmwareResponse{Status: firmware.UnpublishFirmwareStatusNoFirmware}, true}, @@ -30,11 +26,10 @@ func (suite *OcppV2TestSuite) TestUnpublishFirmwareResponseValidation() { {firmware.UnpublishFirmwareResponse{}, false}, {firmware.UnpublishFirmwareResponse{Status: "invalidUnpublishFirmwareStatus"}, false}, } - ExecuteGenericTestTable(t, confirmationTable) + ExecuteGenericTestTable(suite, confirmationTable) } func (suite *OcppV2TestSuite) TestUnpublishFirmwareE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -50,25 +45,25 @@ func (suite *OcppV2TestSuite) TestUnpublishFirmwareE2EMocked() { handler := &MockChargingStationFirmwareHandler{} handler.On("OnUnpublishFirmware", mock.Anything).Return(unpublishFirmwareResponse, nil).Run(func(args mock.Arguments) { request := args.Get(0).(*firmware.UnpublishFirmwareRequest) - assert.Equal(t, checksum, request.Checksum) + suite.Equal(checksum, request.Checksum) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - assert.Nil(t, err) + suite.Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.UnpublishFirmware(wsId, func(resp *firmware.UnpublishFirmwareResponse, err error) { - require.NoError(t, err) - require.NotNil(t, resp) - assert.Equal(t, unpublishFirmwareResponse.Status, resp.Status) + suite.Require().NoError(err) + suite.Require().NotNil(resp) + suite.Equal(unpublishFirmwareResponse.Status, resp.Status) resultChannel <- true }, checksum) - require.Nil(t, err) + suite.Require().Nil(err) if err == nil { result := <-resultChannel - assert.True(t, result) + suite.True(result) } } diff --git a/ocpp2.0.1_test/update_firmware_test.go b/ocpp2.0.1_test/update_firmware_test.go index 89262d6b..ec07a47f 100644 --- a/ocpp2.0.1_test/update_firmware_test.go +++ b/ocpp2.0.1_test/update_firmware_test.go @@ -4,17 +4,14 @@ import ( "fmt" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/firmware" - "github.com/lorenzodonini/ocpp-go/ocpp2.0.1/types" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/firmware" + "github.com/xBlaz3kx/ocpp-go/ocpp2.0.1/types" ) // Test func (suite *OcppV2TestSuite) TestUpdateFirmwareRequestValidation() { - t := suite.T() fw := firmware.Firmware{ Location: "https://someurl", RetrieveDateTime: types.NewDateTime(time.Now()), @@ -36,11 +33,10 @@ func (suite *OcppV2TestSuite) TestUpdateFirmwareRequestValidation() { {firmware.UpdateFirmwareRequest{Retries: newInt(5), RetryInterval: newInt(300), RequestID: 42, Firmware: firmware.Firmware{Location: "https://someurl", InstallDateTime: types.NewDateTime(time.Now()), SigningCertificate: "1337c0de", Signature: "deadc0de"}}, false}, {firmware.UpdateFirmwareRequest{Retries: newInt(5), RetryInterval: newInt(300), RequestID: 42, Firmware: firmware.Firmware{Location: ">512.............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", RetrieveDateTime: types.NewDateTime(time.Now()), InstallDateTime: types.NewDateTime(time.Now()), SigningCertificate: "1337c0de", Signature: "deadc0de"}}, false}, } - ExecuteGenericTestTable(t, requestTable) + ExecuteGenericTestTable(suite, requestTable) } func (suite *OcppV2TestSuite) TestUpdateFirmwareResponseValidation() { - t := suite.T() var responseTable = []GenericTestEntry{ {firmware.UpdateFirmwareResponse{Status: firmware.UpdateFirmwareStatusAccepted, StatusInfo: &types.StatusInfo{ReasonCode: "ok", AdditionalInfo: "someInfo"}}, true}, {firmware.UpdateFirmwareResponse{Status: firmware.UpdateFirmwareStatusAccepted, StatusInfo: &types.StatusInfo{ReasonCode: "ok"}}, true}, @@ -49,11 +45,10 @@ func (suite *OcppV2TestSuite) TestUpdateFirmwareResponseValidation() { {firmware.UpdateFirmwareResponse{Status: "invalidFirmwareUpdateStatus"}, false}, {firmware.UpdateFirmwareResponse{Status: firmware.UpdateFirmwareStatusAccepted, StatusInfo: &types.StatusInfo{}}, false}, } - ExecuteGenericTestTable(t, responseTable) + ExecuteGenericTestTable(suite, responseTable) } func (suite *OcppV2TestSuite) TestUpdateFirmwareE2EMocked() { - t := suite.T() wsId := "test_id" messageId := defaultMessageId wsUrl := "someUrl" @@ -80,40 +75,40 @@ func (suite *OcppV2TestSuite) TestUpdateFirmwareE2EMocked() { handler := &MockChargingStationFirmwareHandler{} handler.On("OnUpdateFirmware", mock.Anything).Return(updateFirmwareResponse, nil).Run(func(args mock.Arguments) { request := args.Get(0).(*firmware.UpdateFirmwareRequest) - require.NotNil(t, request) - require.NotNil(t, request.Retries) - assert.Equal(t, *retries, *request.Retries) - require.NotNil(t, request.RetryInterval) - assert.Equal(t, *retryInterval, *request.RetryInterval) - assert.Equal(t, requestID, request.RequestID) - assert.Equal(t, fw.Location, request.Firmware.Location) - assertDateTimeEquality(t, fw.RetrieveDateTime, request.Firmware.RetrieveDateTime) - assertDateTimeEquality(t, fw.InstallDateTime, request.Firmware.InstallDateTime) - assert.Equal(t, fw.SigningCertificate, request.Firmware.SigningCertificate) - assert.Equal(t, fw.Signature, request.Firmware.Signature) + suite.Require().NotNil(request) + suite.Require().NotNil(request.Retries) + suite.Equal(*retries, *request.Retries) + suite.Require().NotNil(request.RetryInterval) + suite.Equal(*retryInterval, *request.RetryInterval) + suite.Equal(requestID, request.RequestID) + suite.Equal(fw.Location, request.Firmware.Location) + assertDateTimeEquality(suite, fw.RetrieveDateTime, request.Firmware.RetrieveDateTime) + assertDateTimeEquality(suite, fw.InstallDateTime, request.Firmware.InstallDateTime) + suite.Equal(fw.SigningCertificate, request.Firmware.SigningCertificate) + suite.Equal(fw.Signature, request.Firmware.Signature) }) setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true}) setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler) // Run Test suite.csms.Start(8887, "somePath") err := suite.chargingStation.Start(wsUrl) - assert.Nil(t, err) + suite.Nil(err) resultChannel := make(chan bool, 1) err = suite.csms.UpdateFirmware(wsId, func(resp *firmware.UpdateFirmwareResponse, err error) { - assert.Nil(t, err) - require.NotNil(t, resp) - assert.Equal(t, status, resp.Status) - require.NotNil(t, resp.StatusInfo) - assert.Equal(t, statusInfo.ReasonCode, resp.StatusInfo.ReasonCode) - assert.Equal(t, statusInfo.AdditionalInfo, resp.StatusInfo.AdditionalInfo) + suite.Nil(err) + suite.Require().NotNil(resp) + suite.Equal(status, resp.Status) + suite.Require().NotNil(resp.StatusInfo) + suite.Equal(statusInfo.ReasonCode, resp.StatusInfo.ReasonCode) + suite.Equal(statusInfo.AdditionalInfo, resp.StatusInfo.AdditionalInfo) resultChannel <- true }, requestID, fw, func(request *firmware.UpdateFirmwareRequest) { request.Retries = retries request.RetryInterval = retryInterval }) - require.Nil(t, err) + suite.Require().Nil(err) result := <-resultChannel - assert.True(t, result) + suite.True(result) } func (suite *OcppV2TestSuite) TestUpdateFirmwareInvalidEndpoint() { diff --git a/ocppj/central_system_test.go b/ocppj/central_system_test.go index 302ab215..4ddab399 100644 --- a/ocppj/central_system_test.go +++ b/ocppj/central_system_test.go @@ -5,40 +5,38 @@ import ( "fmt" "strconv" "sync" + "sync/atomic" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocppj" - "github.com/lorenzodonini/ocpp-go/ws" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ws" ) func (suite *OcppJTestSuite) TestNewServer() { - s := ocppj.NewServer(nil, nil, nil) - assert.NotNil(suite.T(), s) + s, err := ocppj.NewServer(nil, nil, nil, nil) + suite.Require().NoError(err) + suite.Assert().NotNil(s) } func (suite *OcppJTestSuite) TestServerStart() { suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) suite.centralSystem.Start(8887, "/{ws}") - assert.True(suite.T(), suite.serverDispatcher.IsRunning()) + suite.Assert().True(suite.serverDispatcher.IsRunning()) } func (suite *OcppJTestSuite) TestServerNotStartedError() { - t := suite.T() mockChargePointId := "1234" // Start normally req := newMockRequest("somevalue") err := suite.centralSystem.SendRequest(mockChargePointId, req) - require.Error(t, err, "ocppj server is not started, couldn't send request") - assert.False(t, suite.serverDispatcher.IsRunning()) + suite.Require().Error(err, "ocppj server is not started, couldn't send request") + suite.Assert().False(suite.serverDispatcher.IsRunning()) } func (suite *OcppJTestSuite) TestServerStoppedError() { - t := suite.T() mockChargePointId := "1234" // Start server suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) @@ -48,10 +46,10 @@ func (suite *OcppJTestSuite) TestServerStoppedError() { suite.centralSystem.Stop() // Send message. Expected error time.Sleep(20 * time.Millisecond) - assert.False(t, suite.serverDispatcher.IsRunning()) + suite.Assert().False(suite.serverDispatcher.IsRunning()) req := newMockRequest("somevalue") err := suite.centralSystem.SendRequest(mockChargePointId, req) - assert.Error(t, err, "ocppj server is not started, couldn't send request") + suite.Assert().Error(err, "ocppj server is not started, couldn't send request") } // ----------------- SendRequest tests ----------------- @@ -64,7 +62,7 @@ func (suite *OcppJTestSuite) TestCentralSystemSendRequest() { suite.serverDispatcher.CreateClient(mockChargePointId) mockRequest := newMockRequest("mockValue") err := suite.centralSystem.SendRequest(mockChargePointId, mockRequest) - assert.Nil(suite.T(), err) + suite.Assert().Nil(err) } func (suite *OcppJTestSuite) TestCentralSystemSendInvalidRequest() { @@ -75,7 +73,7 @@ func (suite *OcppJTestSuite) TestCentralSystemSendInvalidRequest() { suite.serverDispatcher.CreateClient(mockChargePointId) mockRequest := newMockRequest("") err := suite.centralSystem.SendRequest(mockChargePointId, mockRequest) - assert.NotNil(suite.T(), err) + suite.Assert().NotNil(err) } func (suite *OcppJTestSuite) TestCentralSystemSendRequestNoValidation() { @@ -89,7 +87,7 @@ func (suite *OcppJTestSuite) TestCentralSystemSendRequestNoValidation() { ocppj.SetMessageValidation(false) defer ocppj.SetMessageValidation(true) err := suite.centralSystem.SendRequest(mockChargePointId, mockRequest) - assert.Nil(suite.T(), err) + suite.Assert().Nil(err) } func (suite *OcppJTestSuite) TestCentralSystemSendInvalidJsonRequest() { @@ -101,12 +99,11 @@ func (suite *OcppJTestSuite) TestCentralSystemSendInvalidJsonRequest() { mockRequest := newMockRequest("somevalue") mockRequest.MockAny = make(chan int) err := suite.centralSystem.SendRequest(mockChargePointId, mockRequest) - require.Error(suite.T(), err) - assert.IsType(suite.T(), &json.UnsupportedTypeError{}, err) + suite.Require().Error(err) + suite.Assert().IsType(&json.UnsupportedTypeError{}, err) } func (suite *OcppJTestSuite) TestCentralSystemInvalidMessageHook() { - t := suite.T() mockChargePointId := "1234" mockChargePoint := NewMockWebSocket(mockChargePointId) // Prepare invalid payload @@ -115,53 +112,53 @@ func (suite *OcppJTestSuite) TestCentralSystemInvalidMessageHook() { "mockValue": float64(1234), } serializedPayload, err := json.Marshal(mockPayload) - require.NoError(t, err) + suite.Require().NoError(err) invalidMessage := fmt.Sprintf("[2,\"%v\",\"%s\",%v]", mockID, MockFeatureName, string(serializedPayload)) expectedError := fmt.Sprintf("[4,\"%v\",\"%v\",\"%v\",{}]", mockID, ocppj.FormatErrorType(suite.centralSystem), "json: cannot unmarshal number into Go struct field MockRequest.mockValue of type string") writeHook := suite.mockServer.On("Write", mockChargePointId, mock.Anything).Return(nil).Run(func(args mock.Arguments) { data := args.Get(1).([]byte) - assert.Equal(t, expectedError, string(data)) + suite.Assert().Equal(expectedError, string(data)) }) suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) // Setup hook 1 suite.centralSystem.SetInvalidMessageHook(func(client ws.Channel, err *ocpp.Error, rawMessage string, parsedFields []interface{}) *ocpp.Error { - assert.Equal(t, mockChargePoint.ID(), client.ID()) + suite.Assert().Equal(mockChargePoint.ID(), client.ID()) // Verify the correct fields are passed to the hook. Content is very low-level, since parsing failed - assert.Equal(t, float64(ocppj.CALL), parsedFields[0]) - assert.Equal(t, mockID, parsedFields[1]) - assert.Equal(t, MockFeatureName, parsedFields[2]) - assert.Equal(t, mockPayload, parsedFields[3]) + suite.Assert().Equal(float64(ocppj.CALL), parsedFields[0]) + suite.Assert().Equal(mockID, parsedFields[1]) + suite.Assert().Equal(MockFeatureName, parsedFields[2]) + suite.Assert().Equal(mockPayload, parsedFields[3]) return nil }) suite.centralSystem.Start(8887, "/{ws}") // Trigger incoming invalid CALL err = suite.mockServer.MessageHandler(mockChargePoint, []byte(invalidMessage)) ocppErr, ok := err.(*ocpp.Error) - require.True(t, ok) - assert.Equal(t, ocppj.FormatErrorType(suite.centralSystem), ocppErr.Code) + suite.Require().True(ok) + suite.Assert().Equal(ocppj.FormatErrorType(suite.centralSystem), ocppErr.Code) // Setup hook 2 mockError := ocpp.NewError(ocppj.InternalError, "custom error", mockID) expectedError = fmt.Sprintf("[4,\"%v\",\"%v\",\"%v\",{}]", mockError.MessageId, mockError.Code, mockError.Description) writeHook.Run(func(args mock.Arguments) { data := args.Get(1).([]byte) - assert.Equal(t, expectedError, string(data)) + suite.Assert().Equal(expectedError, string(data)) }) suite.centralSystem.SetInvalidMessageHook(func(client ws.Channel, err *ocpp.Error, rawMessage string, parsedFields []interface{}) *ocpp.Error { - assert.Equal(t, mockChargePoint.ID(), client.ID()) + suite.Assert().Equal(mockChargePoint.ID(), client.ID()) // Verify the correct fields are passed to the hook. Content is very low-level, since parsing failed - assert.Equal(t, float64(ocppj.CALL), parsedFields[0]) - assert.Equal(t, mockID, parsedFields[1]) - assert.Equal(t, MockFeatureName, parsedFields[2]) - assert.Equal(t, mockPayload, parsedFields[3]) + suite.Assert().Equal(float64(ocppj.CALL), parsedFields[0]) + suite.Assert().Equal(mockID, parsedFields[1]) + suite.Assert().Equal(MockFeatureName, parsedFields[2]) + suite.Assert().Equal(mockPayload, parsedFields[3]) return mockError }) // Trigger incoming invalid CALL that returns custom error err = suite.mockServer.MessageHandler(mockChargePoint, []byte(invalidMessage)) ocppErr, ok = err.(*ocpp.Error) - require.True(t, ok) - assert.Equal(t, mockError.Code, ocppErr.Code) - assert.Equal(t, mockError.Description, ocppErr.Description) - assert.Equal(t, mockError.MessageId, ocppErr.MessageId) + suite.Require().True(ok) + suite.Assert().Equal(mockError.Code, ocppErr.Code) + suite.Assert().Equal(mockError.Description, ocppErr.Description) + suite.Assert().Equal(mockError.MessageId, ocppErr.MessageId) } func (suite *OcppJTestSuite) TestServerSendInvalidCall() { @@ -174,41 +171,39 @@ func (suite *OcppJTestSuite) TestServerSendInvalidCall() { // Delete existing profiles and test error suite.centralSystem.Profiles = []*ocpp.Profile{} err := suite.centralSystem.SendRequest(mockChargePointId, mockRequest) - assert.Error(suite.T(), err, fmt.Sprintf("Couldn't create Call for unsupported action %v", mockRequest.GetFeatureName())) + suite.Assert().Error(err, fmt.Sprintf("Couldn't create Call for unsupported action %v", mockRequest.GetFeatureName())) } func (suite *OcppJTestSuite) TestCentralSystemSendRequestFailed() { - t := suite.T() mockChargePointId := "1234" var callID string suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) suite.mockServer.On("Write", mock.AnythingOfType("string"), mock.Anything).Return(fmt.Errorf("networkError")).Run(func(args mock.Arguments) { clientID := args.String(0) q, ok := suite.serverRequestMap.Get(clientID) - require.True(t, ok) - require.False(t, q.IsEmpty()) + suite.Require().True(ok) + suite.Require().False(q.IsEmpty()) req := q.Peek().(ocppj.RequestBundle) callID = req.Call.GetUniqueId() // Before error is returned, the request must still be pending _, ok = suite.centralSystem.RequestState.GetClientState(mockChargePointId).GetPendingRequest(callID) - assert.True(t, ok) + suite.Assert().True(ok) }) suite.centralSystem.Start(8887, "/{ws}") suite.serverDispatcher.CreateClient(mockChargePointId) mockRequest := newMockRequest("mockValue") err := suite.centralSystem.SendRequest(mockChargePointId, mockRequest) // TODO: currently the network error is not returned by SendRequest, but is only generated internally - assert.Nil(t, err) + suite.Assert().Nil(err) // Assert that pending request was removed time.Sleep(500 * time.Millisecond) _, ok := suite.centralSystem.RequestState.GetClientState(mockChargePointId).GetPendingRequest(callID) - assert.False(t, ok) + suite.Assert().False(ok) } // ----------------- SendResponse tests ----------------- func (suite *OcppJTestSuite) TestCentralSystemSendConfirmation() { - t := suite.T() mockChargePointId := "0101" mockUniqueId := "1234" suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) @@ -217,11 +212,10 @@ func (suite *OcppJTestSuite) TestCentralSystemSendConfirmation() { suite.serverDispatcher.CreateClient(mockChargePointId) mockConfirmation := newMockConfirmation("mockValue") err := suite.centralSystem.SendResponse(mockChargePointId, mockUniqueId, mockConfirmation) - assert.Nil(t, err) + suite.Assert().Nil(err) } func (suite *OcppJTestSuite) TestCentralSystemSendInvalidConfirmation() { - t := suite.T() mockChargePointId := "0101" mockUniqueId := "6789" suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) @@ -231,11 +225,10 @@ func (suite *OcppJTestSuite) TestCentralSystemSendInvalidConfirmation() { mockConfirmation := newMockConfirmation("") // This is allowed. Endpoint doesn't keep track of incoming requests, but only outgoing ones err := suite.centralSystem.SendResponse(mockChargePointId, mockUniqueId, mockConfirmation) - assert.NotNil(t, err) + suite.Assert().NotNil(err) } func (suite *OcppJTestSuite) TestCentralSystemSendConfirmationNoValidation() { - t := suite.T() mockChargePointId := "0101" mockUniqueId := "6789" suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) @@ -248,11 +241,10 @@ func (suite *OcppJTestSuite) TestCentralSystemSendConfirmationNoValidation() { defer ocppj.SetMessageValidation(true) // This is allowed. Endpoint doesn't keep track of incoming requests, but only outgoing ones err := suite.centralSystem.SendResponse(mockChargePointId, mockUniqueId, mockConfirmation) - assert.Nil(t, err) + suite.Assert().Nil(err) } func (suite *OcppJTestSuite) TestCentralSystemSendConfirmationFailed() { - t := suite.T() mockChargePointId := "0101" mockUniqueId := "1234" suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) @@ -261,14 +253,13 @@ func (suite *OcppJTestSuite) TestCentralSystemSendConfirmationFailed() { suite.serverDispatcher.CreateClient(mockChargePointId) mockConfirmation := newMockConfirmation("mockValue") err := suite.centralSystem.SendResponse(mockChargePointId, mockUniqueId, mockConfirmation) - assert.NotNil(t, err) + suite.Assert().NotNil(err) expectedErr := fmt.Sprintf("ocpp message (%v): GenericError - networkError", mockUniqueId) - assert.ErrorContains(t, err, expectedErr) + suite.Assert().ErrorContains(err, expectedErr) } // SendError func (suite *OcppJTestSuite) TestCentralSystemSendError() { - t := suite.T() mockChargePointId := "0101" mockUniqueId := "1234" mockDescription := "mockDescription" @@ -277,11 +268,10 @@ func (suite *OcppJTestSuite) TestCentralSystemSendError() { suite.centralSystem.Start(8887, "/{ws}") suite.serverDispatcher.CreateClient(mockChargePointId) err := suite.centralSystem.SendError(mockChargePointId, mockUniqueId, ocppj.GenericError, mockDescription, nil) - assert.Nil(t, err) + suite.Assert().Nil(err) } func (suite *OcppJTestSuite) TestCentralSystemSendInvalidError() { - t := suite.T() mockChargePointId := "0101" mockUniqueId := "6789" mockDescription := "mockDescription" @@ -290,11 +280,10 @@ func (suite *OcppJTestSuite) TestCentralSystemSendInvalidError() { suite.centralSystem.Start(8887, "/{ws}") suite.serverDispatcher.CreateClient(mockChargePointId) err := suite.centralSystem.SendError(mockChargePointId, mockUniqueId, "InvalidErrorCode", mockDescription, nil) - assert.NotNil(t, err) + suite.Assert().NotNil(err) } func (suite *OcppJTestSuite) TestCentralSystemSendErrorFailed() { - t := suite.T() mockChargePointId := "0101" mockUniqueId := "1234" suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) @@ -303,20 +292,19 @@ func (suite *OcppJTestSuite) TestCentralSystemSendErrorFailed() { suite.serverDispatcher.CreateClient(mockChargePointId) mockConfirmation := newMockConfirmation("mockValue") err := suite.centralSystem.SendResponse(mockChargePointId, mockUniqueId, mockConfirmation) - assert.NotNil(t, err) + suite.Assert().NotNil(err) expectedErr := fmt.Sprintf("ocpp message (%v): GenericError - networkError", mockUniqueId) - assert.ErrorContains(t, err, expectedErr) + suite.Assert().ErrorContains(err, expectedErr) } func (suite *OcppJTestSuite) TestCentralSystemHandleFailedResponse() { - t := suite.T() msgC := make(chan []byte, 1) mockChargePointID := "0101" mockUniqueID := "1234" suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) suite.mockServer.On("Write", mock.AnythingOfType("string"), mock.Anything).Return(nil).Run(func(args mock.Arguments) { data, ok := args.Get(1).([]byte) - require.True(t, ok) + suite.Require().True(ok) msgC <- data }) suite.centralSystem.Start(8887, "/{ws}") @@ -324,72 +312,77 @@ func (suite *OcppJTestSuite) TestCentralSystemHandleFailedResponse() { var callResult *ocppj.CallResult var callError *ocppj.CallError var err error + // 1. occurrence validation error mockField := "CallResult.Payload.MockValue" mockResponse := newMockConfirmation("") callResult, err = suite.centralSystem.CreateCallResult(mockResponse, mockUniqueID) - require.Error(t, err) - require.Nil(t, callResult) + suite.Require().Error(err) + suite.Require().Nil(callResult) suite.centralSystem.HandleFailedResponseError(mockChargePointID, mockUniqueID, err, mockResponse.GetFeatureName()) rawResponse := <-msgC expectedErr := fmt.Sprintf(`[4,"%v","%v","Field %s required but not found for feature %s",{}]`, mockUniqueID, ocppj.OccurrenceConstraintErrorType(suite.centralSystem), mockField, mockResponse.GetFeatureName()) - assert.Equal(t, expectedErr, string(rawResponse)) + suite.Assert().Equal(expectedErr, string(rawResponse)) + // 2. property constraint validation error val := "len4" minParamLength := "5" mockResponse = newMockConfirmation(val) callResult, err = suite.centralSystem.CreateCallResult(mockResponse, mockUniqueID) - require.Error(t, err) - require.Nil(t, callResult) + suite.Require().Error(err) + suite.Require().Nil(callResult) suite.centralSystem.HandleFailedResponseError(mockChargePointID, mockUniqueID, err, mockResponse.GetFeatureName()) rawResponse = <-msgC expectedErr = fmt.Sprintf(`[4,"%v","%v","Field %s must be minimum %s, but was %d for feature %s",{}]`, mockUniqueID, ocppj.PropertyConstraintViolation, mockField, minParamLength, len(val), mockResponse.GetFeatureName()) - assert.Equal(t, expectedErr, string(rawResponse)) + suite.Assert().Equal(expectedErr, string(rawResponse)) + // 3. profile not supported mockUnsupportedResponse := &MockUnsupportedResponse{MockValue: "someValue"} callResult, err = suite.centralSystem.CreateCallResult(mockUnsupportedResponse, mockUniqueID) - require.Error(t, err) - require.Nil(t, callResult) + suite.Require().Error(err) + suite.Require().Nil(callResult) suite.centralSystem.HandleFailedResponseError(mockChargePointID, mockUniqueID, err, mockUnsupportedResponse.GetFeatureName()) rawResponse = <-msgC expectedErr = fmt.Sprintf(`[4,"%v","%v","couldn't create Call Result for unsupported action %s",{}]`, mockUniqueID, ocppj.NotSupported, mockUnsupportedResponse.GetFeatureName()) - assert.Equal(t, expectedErr, string(rawResponse)) + suite.Assert().Equal(expectedErr, string(rawResponse)) + // 4. ocpp error validation failed invalidErrorCode := "InvalidErrorCode" callError, err = suite.centralSystem.CreateCallError(mockUniqueID, ocpp.ErrorCode(invalidErrorCode), "", nil) - require.Error(t, err) - require.Nil(t, callError) + suite.Require().Error(err) + suite.Require().Nil(callError) suite.centralSystem.HandleFailedResponseError(mockChargePointID, mockUniqueID, err, "") rawResponse = <-msgC expectedErr = fmt.Sprintf(`[4,"%v","%v","Key: 'CallError.ErrorCode' Error:Field validation for 'ErrorCode' failed on the 'errorCode' tag",{}]`, mockUniqueID, ocppj.GenericError) - assert.Equal(t, expectedErr, string(rawResponse)) + suite.Assert().Equal(expectedErr, string(rawResponse)) + // 5. marshaling err err = suite.centralSystem.SendError(mockChargePointID, mockUniqueID, ocppj.SecurityError, "", make(chan struct{})) - require.Error(t, err) + suite.Require().Error(err) suite.centralSystem.HandleFailedResponseError(mockChargePointID, mockUniqueID, err, "") rawResponse = <-msgC expectedErr = fmt.Sprintf(`[4,"%v","%v","json: unsupported type: chan struct {}",{}]`, mockUniqueID, ocppj.GenericError) - assert.Equal(t, expectedErr, string(rawResponse)) + suite.Assert().Equal(expectedErr, string(rawResponse)) + // 6. network error rawErr := fmt.Sprintf("couldn't write to websocket. No socket with id %s is open", mockChargePointID) err = ocpp.NewError(ocppj.GenericError, rawErr, mockUniqueID) suite.centralSystem.HandleFailedResponseError(mockChargePointID, mockUniqueID, err, "") rawResponse = <-msgC expectedErr = fmt.Sprintf(`[4,"%v","%v","%s",{}]`, mockUniqueID, ocppj.GenericError, rawErr) - assert.Equal(t, expectedErr, string(rawResponse)) + suite.Assert().Equal(expectedErr, string(rawResponse)) } // ----------------- Handlers tests ----------------- func (suite *OcppJTestSuite) TestCentralSystemNewClientHandler() { - t := suite.T() mockClientID := "1234" connectedC := make(chan bool, 1) suite.centralSystem.SetNewClientHandler(func(client ws.Channel) { - assert.Equal(t, mockClientID, client.ID()) + suite.Assert().Equal(mockClientID, client.ID()) connectedC <- true }) suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return() @@ -399,23 +392,22 @@ func (suite *OcppJTestSuite) TestCentralSystemNewClientHandler() { channel := NewMockWebSocket(mockClientID) suite.mockServer.NewClientHandler(channel) ok := <-connectedC - assert.True(t, ok) + suite.Assert().True(ok) // client state was created _, ok = suite.serverRequestMap.Get(mockClientID) - assert.True(t, ok) + suite.Assert().True(ok) } func (suite *OcppJTestSuite) TestCentralSystemDisconnectedHandler() { - t := suite.T() mockClientID := "1234" connectedC := make(chan bool, 1) disconnectedC := make(chan bool, 1) suite.centralSystem.SetNewClientHandler(func(client ws.Channel) { - assert.Equal(t, mockClientID, client.ID()) + suite.Assert().Equal(mockClientID, client.ID()) connectedC <- true }) suite.centralSystem.SetDisconnectedClientHandler(func(client ws.Channel) { - assert.Equal(t, mockClientID, client.ID()) + suite.Assert().Equal(mockClientID, client.ID()) disconnectedC <- true }) suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return() @@ -425,24 +417,23 @@ func (suite *OcppJTestSuite) TestCentralSystemDisconnectedHandler() { channel := NewMockWebSocket(mockClientID) suite.mockServer.NewClientHandler(channel) ok := <-connectedC - assert.True(t, ok) + suite.Assert().True(ok) // Simulate client disconnection suite.mockServer.DisconnectedClientHandler(channel) ok = <-disconnectedC - assert.True(t, ok) + suite.Assert().True(ok) } func (suite *OcppJTestSuite) TestCentralSystemRequestHandler() { - t := suite.T() mockChargePointId := "1234" mockUniqueId := "5678" mockValue := "someValue" mockRequest := fmt.Sprintf(`[2,"%v","%v",{"mockValue":"%v"}]`, mockUniqueId, MockFeatureName, mockValue) suite.centralSystem.SetRequestHandler(func(chargePoint ws.Channel, request ocpp.Request, requestId string, action string) { - assert.Equal(t, mockChargePointId, chargePoint.ID()) - assert.Equal(t, mockUniqueId, requestId) - assert.Equal(t, MockFeatureName, action) - assert.NotNil(t, request) + suite.Assert().Equal(mockChargePointId, chargePoint.ID()) + suite.Assert().Equal(mockUniqueId, requestId) + suite.Assert().Equal(MockFeatureName, action) + suite.Assert().NotNil(request) }) suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return() suite.centralSystem.Start(8887, "somePath") @@ -450,20 +441,19 @@ func (suite *OcppJTestSuite) TestCentralSystemRequestHandler() { // Simulate charge point message channel := NewMockWebSocket(mockChargePointId) err := suite.mockServer.MessageHandler(channel, []byte(mockRequest)) - assert.Nil(t, err) + suite.Assert().Nil(err) } func (suite *OcppJTestSuite) TestCentralSystemConfirmationHandler() { - t := suite.T() mockChargePointId := "1234" mockUniqueId := "5678" mockValue := "someValue" mockRequest := newMockRequest("testValue") mockConfirmation := fmt.Sprintf(`[3,"%v",{"mockValue":"%v"}]`, mockUniqueId, mockValue) suite.centralSystem.SetResponseHandler(func(chargePoint ws.Channel, confirmation ocpp.Response, requestId string) { - assert.Equal(t, mockChargePointId, chargePoint.ID()) - assert.Equal(t, mockUniqueId, requestId) - assert.NotNil(t, confirmation) + suite.Assert().Equal(mockChargePointId, chargePoint.ID()) + suite.Assert().Equal(mockUniqueId, requestId) + suite.Assert().NotNil(confirmation) }) suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) // Start central system @@ -474,11 +464,10 @@ func (suite *OcppJTestSuite) TestCentralSystemConfirmationHandler() { // Simulate charge point message channel := NewMockWebSocket(mockChargePointId) err := suite.mockServer.MessageHandler(channel, []byte(mockConfirmation)) - assert.Nil(t, err) + suite.Assert().Nil(err) } func (suite *OcppJTestSuite) TestCentralSystemErrorHandler() { - t := suite.T() mockChargePointId := "1234" mockUniqueId := "5678" mockErrorCode := ocppj.GenericError @@ -489,11 +478,11 @@ func (suite *OcppJTestSuite) TestCentralSystemErrorHandler() { mockRequest := newMockRequest("testValue") mockError := fmt.Sprintf(`[4,"%v","%v","%v",{"details":"%v"}]`, mockUniqueId, mockErrorCode, mockErrorDescription, mockValue) suite.centralSystem.SetErrorHandler(func(chargePoint ws.Channel, err *ocpp.Error, details interface{}) { - assert.Equal(t, mockChargePointId, chargePoint.ID()) - assert.Equal(t, mockUniqueId, err.MessageId) - assert.Equal(t, mockErrorCode, err.Code) - assert.Equal(t, mockErrorDescription, err.Description) - assert.Equal(t, mockErrorDetails, details) + suite.Assert().Equal(mockChargePointId, chargePoint.ID()) + suite.Assert().Equal(mockUniqueId, err.MessageId) + suite.Assert().Equal(mockErrorCode, err.Code) + suite.Assert().Equal(mockErrorDescription, err.Description) + suite.Assert().Equal(mockErrorDetails, details) }) suite.mockServer.On("Write", mock.AnythingOfType("string"), mock.Anything).Return(nil) suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) @@ -505,7 +494,7 @@ func (suite *OcppJTestSuite) TestCentralSystemErrorHandler() { // Simulate charge point message channel := NewMockWebSocket(mockChargePointId) err := suite.mockServer.MessageHandler(channel, []byte(mockError)) - assert.Nil(t, err) + suite.Assert().Nil(err) } func addMockPendingRequest(suite *OcppJTestSuite, mockRequest ocpp.Request, mockUniqueID string, mockChargePointID string) { @@ -524,7 +513,6 @@ func addMockPendingRequest(suite *OcppJTestSuite, mockRequest ocpp.Request, mock // ----------------- Queue processing tests ----------------- func (suite *OcppJTestSuite) TestServerEnqueueRequest() { - t := suite.T() suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) suite.mockServer.On("Write", mock.AnythingOfType("string"), mock.Anything).Return(nil) // Start normally @@ -534,65 +522,68 @@ func (suite *OcppJTestSuite) TestServerEnqueueRequest() { // Simulate request req := newMockRequest("somevalue") err := suite.centralSystem.SendRequest(mockChargePointId, req) - require.Nil(t, err) + suite.Require().Nil(err) time.Sleep(500 * time.Millisecond) // Message was sent, but element should still be in queue q, ok := suite.serverRequestMap.Get(mockChargePointId) - require.True(t, ok) - assert.False(t, q.IsEmpty()) - assert.Equal(t, 1, q.Size()) + suite.Require().True(ok) + suite.Assert().False(q.IsEmpty()) + suite.Assert().Equal(1, q.Size()) // Analyze enqueued bundle peeked := q.Peek() - require.NotNil(t, peeked) + suite.Require().NotNil(peeked) bundle, ok := peeked.(ocppj.RequestBundle) - require.True(t, ok) - require.NotNil(t, bundle) - assert.Equal(t, req.GetFeatureName(), bundle.Call.Action) + suite.Require().True(ok) + suite.Require().NotNil(bundle) + suite.Assert().Equal(req.GetFeatureName(), bundle.Call.Action) marshaled, err := bundle.Call.MarshalJSON() - require.Nil(t, err) - assert.Equal(t, marshaled, bundle.Data) + suite.Require().Nil(err) + suite.Assert().Equal(marshaled, bundle.Data) } func (suite *OcppJTestSuite) TestEnqueueMultipleRequests() { - t := suite.T() - messagesToQueue := 5 - sentMessages := 0 + var messagesToQueue atomic.Int64 + var sentMessages atomic.Int64 + messagesToQueue.Store(5) + mockChargePointId := "1234" suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) suite.mockServer.On("Write", mock.AnythingOfType("string"), mock.Anything).Run(func(args mock.Arguments) { - sentMessages += 1 + sentMessages.Add(1) }).Return(nil) // Start normally suite.centralSystem.Start(8887, "/{ws}") suite.serverDispatcher.CreateClient(mockChargePointId) - for i := 0; i < messagesToQueue; i++ { + + for i := 0; i < int(messagesToQueue.Load()); i++ { req := newMockRequest(fmt.Sprintf("request-%v", i)) err := suite.centralSystem.SendRequest(mockChargePointId, req) - require.Nil(t, err) + suite.Require().Nil(err) } time.Sleep(500 * time.Millisecond) + // Only one message was sent, but all elements should still be in queue - assert.Equal(t, 1, sentMessages) + suite.Assert().Equal(int64(1), sentMessages.Load()) q, ok := suite.serverRequestMap.Get(mockChargePointId) - require.True(t, ok) - assert.False(t, q.IsEmpty()) - assert.Equal(t, messagesToQueue, q.Size()) + suite.Require().True(ok) + suite.Assert().False(q.IsEmpty()) + suite.Assert().Equal(int(messagesToQueue.Load()), q.Size()) + // Analyze enqueued bundle var i int for !q.IsEmpty() { popped := q.Pop() - require.NotNil(t, popped) + suite.Require().NotNil(popped) bundle, ok := popped.(ocppj.RequestBundle) - require.True(t, ok) - require.NotNil(t, bundle) - assert.Equal(t, MockFeatureName, bundle.Call.Action) + suite.Require().True(ok) + suite.Require().NotNil(bundle) + suite.Assert().Equal(MockFeatureName, bundle.Call.Action) i++ } - assert.Equal(t, messagesToQueue, i) + suite.Assert().Equal(int(messagesToQueue.Load()), i) } func (suite *OcppJTestSuite) TestRequestQueueFull() { - t := suite.T() messagesToQueue := queueCapacity mockChargePointId := "1234" suite.mockServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) @@ -603,17 +594,16 @@ func (suite *OcppJTestSuite) TestRequestQueueFull() { for i := 0; i < messagesToQueue; i++ { req := newMockRequest(fmt.Sprintf("request-%v", i)) err := suite.centralSystem.SendRequest(mockChargePointId, req) - require.Nil(t, err) + suite.Require().Nil(err) } // Queue is now full. Trying to send an additional message should throw an error req := newMockRequest("full") err := suite.centralSystem.SendRequest(mockChargePointId, req) - require.NotNil(t, err) - assert.Equal(t, "request queue is full, cannot push new element", err.Error()) + suite.Require().NotNil(err) + suite.Assert().Equal("request queue is full, cannot push new element", err.Error()) } func (suite *OcppJTestSuite) TestParallelRequests() { - t := suite.T() messagesToQueue := 10 sentMessages := 0 mockChargePointId := "1234" @@ -628,16 +618,16 @@ func (suite *OcppJTestSuite) TestParallelRequests() { go func() { req := newMockRequest("someReq") err := suite.centralSystem.SendRequest(mockChargePointId, req) - require.Nil(t, err) + suite.Require().Nil(err) }() } time.Sleep(1000 * time.Millisecond) // Only one message was sent, but all elements should still be in queue q, ok := suite.serverRequestMap.Get(mockChargePointId) - require.True(t, ok) - assert.False(t, q.IsEmpty()) - assert.Equal(t, messagesToQueue, q.Size()) - assert.Equal(t, 1, sentMessages) + suite.Require().True(ok) + suite.Assert().False(q.IsEmpty()) + suite.Assert().Equal(messagesToQueue, q.Size()) + suite.Assert().Equal(1, sentMessages) } // TestRequestFlow tests a typical flow with multiple request-responses, sent to different clients. @@ -666,7 +656,7 @@ func (suite *OcppJTestSuite) TestServerRequestFlow() { data := args.Get(1).([]byte) state := suite.centralSystem.RequestState.GetClientState(wsID) call := ParseCall(&suite.centralSystem.Endpoint, state, string(data), t) - require.NotNil(t, call) + suite.Require().NotNil(call) sendResponseTrigger <- triggerData{clientID: wsID, call: call} }).Return(nil) // Mocked response generator @@ -682,12 +672,12 @@ func (suite *OcppJTestSuite) TestServerRequestFlow() { // Get original request to generate meaningful response call := d.call q, ok := suite.serverRequestMap.Get(d.clientID) - require.True(t, ok) - assert.False(t, q.IsEmpty()) + suite.Require().True(ok) + suite.Assert().False(q.IsEmpty()) peeked := q.Peek() bundle, _ := peeked.(ocppj.RequestBundle) - require.NotNil(t, bundle) - assert.Equal(t, call.UniqueId, bundle.Call.UniqueId) + suite.Require().NotNil(bundle) + suite.Assert().Equal(call.UniqueId, bundle.Call.UniqueId) req, _ := call.Payload.(*MockRequest) // Send response back to server var data []byte @@ -697,27 +687,27 @@ func (suite *OcppJTestSuite) TestServerRequestFlow() { // Send CallResult resp := newMockConfirmation("someResp") res, err := suite.centralSystem.CreateCallResult(resp, call.GetUniqueId()) - require.Nil(t, err) + suite.Require().Nil(err) data, err = res.MarshalJSON() - require.Nil(t, err) + suite.Require().Nil(err) } else { // Send CallError res, err := suite.centralSystem.CreateCallError(call.GetUniqueId(), ocppj.GenericError, fmt.Sprintf("error-%v", req.MockValue), nil) - require.Nil(t, err) + suite.Require().Nil(err) data, err = res.MarshalJSON() - require.Nil(t, err) + suite.Require().Nil(err) } wsChannel := mockChargePoints[d.clientID] err = suite.mockServer.MessageHandler(wsChannel, data) // Triggers ocppMessageHandler - require.Nil(t, err) + suite.Require().Nil(err) // Make sure the top queue element was popped mutex.Lock() processedMessages += 1 peeked = q.Peek() if peeked != nil { bundle, _ := peeked.(ocppj.RequestBundle) - require.NotNil(t, bundle) - assert.NotEqual(t, call.UniqueId, bundle.Call.UniqueId) + suite.Require().NotNil(bundle) + suite.Assert().NotEqual(call.UniqueId, bundle.Call.UniqueId) } mutex.Unlock() wg.Done() @@ -738,14 +728,14 @@ func (suite *OcppJTestSuite) TestServerRequestFlow() { go func(j int, clientID string) { req := newMockRequest(fmt.Sprintf("%v", j)) err := suite.centralSystem.SendRequest(clientID, req) - require.Nil(t, err) + suite.Require().Nil(err) }(i, chargePointTarget) } // Wait for processing to complete wg.Wait() close(sendResponseTrigger) q, _ := suite.serverRequestMap.Get(mockChargePoint1) - assert.True(t, q.IsEmpty()) + suite.Assert().True(q.IsEmpty()) q, _ = suite.serverRequestMap.Get(mockChargePoint2) - assert.True(t, q.IsEmpty()) + suite.Assert().True(q.IsEmpty()) } diff --git a/ocppj/charge_point_test.go b/ocppj/charge_point_test.go index 0b0b8ea8..dd3333df 100644 --- a/ocppj/charge_point_test.go +++ b/ocppj/charge_point_test.go @@ -7,48 +7,45 @@ import ( "sync" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocppj" ) // ----------------- Start tests ----------------- func (suite *OcppJTestSuite) TestNewClient() { clientID := "mock_id" - c := ocppj.NewClient(clientID, suite.mockClient, nil, nil) - assert.NotNil(suite.T(), c) - assert.Equal(suite.T(), clientID, c.Id) + c, err := ocppj.NewClient(clientID, suite.mockClient, nil, nil, nil) + suite.Assert().NoError(err) + suite.Assert().NotNil(c) + suite.Assert().Equal(clientID, c.Id) } func (suite *OcppJTestSuite) TestChargePointStart() { suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(nil) err := suite.chargePoint.Start("someUrl") - assert.Nil(suite.T(), err) - assert.True(suite.T(), suite.clientDispatcher.IsRunning()) + suite.Assert().Nil(err) + suite.Assert().True(suite.clientDispatcher.IsRunning()) } func (suite *OcppJTestSuite) TestChargePointStartFailed() { suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(fmt.Errorf("startError")) err := suite.chargePoint.Start("someUrl") - assert.NotNil(suite.T(), err) + suite.Assert().NotNil(err) } func (suite *OcppJTestSuite) TestClientNotStartedError() { - t := suite.T() // Start normally req := newMockRequest("somevalue") err := suite.chargePoint.SendRequest(req) - require.NotNil(t, err) - assert.Equal(t, "ocppj client is not started, couldn't send request", err.Error()) - require.True(t, suite.clientRequestQueue.IsEmpty()) + suite.Require().NotNil(err) + suite.Assert().Equal("ocppj client is not started, couldn't send request", err.Error()) + suite.Require().True(suite.clientRequestQueue.IsEmpty()) } func (suite *OcppJTestSuite) TestClientStoppedError() { - t := suite.T() // Start client suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(nil) suite.mockClient.On("Stop").Return(nil).Run(func(args mock.Arguments) { @@ -57,16 +54,16 @@ func (suite *OcppJTestSuite) TestClientStoppedError() { }) call := suite.mockClient.On("IsConnected").Return(true) err := suite.chargePoint.Start("someUrl") - require.NoError(t, err) + suite.Require().NoError(err) // Stop client suite.chargePoint.Stop() // Send message. Expected error time.Sleep(20 * time.Millisecond) call.Return(false) - assert.False(t, suite.clientDispatcher.IsRunning()) + suite.Assert().False(suite.clientDispatcher.IsRunning()) req := newMockRequest("somevalue") err = suite.chargePoint.SendRequest(req) - assert.Error(t, err, "ocppj client is not started, couldn't send request") + suite.Assert().Error(err, "ocppj client is not started, couldn't send request") } // ----------------- SendRequest tests ----------------- @@ -77,7 +74,7 @@ func (suite *OcppJTestSuite) TestChargePointSendRequest() { _ = suite.chargePoint.Start("someUrl") mockRequest := newMockRequest("mockValue") err := suite.chargePoint.SendRequest(mockRequest) - assert.Nil(suite.T(), err) + suite.Assert().Nil(err) } func (suite *OcppJTestSuite) TestChargePointSendInvalidRequest() { @@ -86,7 +83,7 @@ func (suite *OcppJTestSuite) TestChargePointSendInvalidRequest() { _ = suite.chargePoint.Start("someUrl") mockRequest := newMockRequest("") err := suite.chargePoint.SendRequest(mockRequest) - require.NotNil(suite.T(), err) + suite.Require().NotNil(err) } func (suite *OcppJTestSuite) TestChargePointSendRequestNoValidation() { @@ -98,7 +95,7 @@ func (suite *OcppJTestSuite) TestChargePointSendRequestNoValidation() { ocppj.SetMessageValidation(false) defer ocppj.SetMessageValidation(true) err := suite.chargePoint.SendRequest(mockRequest) - assert.Nil(suite.T(), err) + suite.Assert().Nil(err) } func (suite *OcppJTestSuite) TestChargePointSendInvalidJsonRequest() { @@ -108,63 +105,62 @@ func (suite *OcppJTestSuite) TestChargePointSendInvalidJsonRequest() { mockRequest := newMockRequest("somevalue") mockRequest.MockAny = make(chan int) err := suite.chargePoint.SendRequest(mockRequest) - require.Error(suite.T(), err) - assert.IsType(suite.T(), &json.UnsupportedTypeError{}, err) + suite.Require().Error(err) + suite.Assert().IsType(&json.UnsupportedTypeError{}, err) } func (suite *OcppJTestSuite) TestChargePointInvalidMessageHook() { - t := suite.T() // Prepare invalid payload mockID := "1234" mockPayload := map[string]interface{}{ "mockValue": float64(1234), } serializedPayload, err := json.Marshal(mockPayload) - require.NoError(t, err) + suite.Require().NoError(err) invalidMessage := fmt.Sprintf("[2,\"%v\",\"%s\",%v]", mockID, MockFeatureName, string(serializedPayload)) expectedError := fmt.Sprintf("[4,\"%v\",\"%v\",\"%v\",{}]", mockID, ocppj.FormatErrorType(suite.chargePoint), "json: cannot unmarshal number into Go struct field MockRequest.mockValue of type string") writeHook := suite.mockClient.On("Write", mock.Anything).Return(nil).Run(func(args mock.Arguments) { data := args.Get(0).([]byte) - assert.Equal(t, expectedError, string(data)) + suite.Assert().Equal(expectedError, string(data)) }) suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(nil) // Setup hook 1 suite.chargePoint.SetInvalidMessageHook(func(err *ocpp.Error, rawMessage string, parsedFields []interface{}) *ocpp.Error { // Verify the correct fields are passed to the hook. Content is very low-level, since parsing failed - assert.Equal(t, float64(ocppj.CALL), parsedFields[0]) - assert.Equal(t, mockID, parsedFields[1]) - assert.Equal(t, MockFeatureName, parsedFields[2]) - assert.Equal(t, mockPayload, parsedFields[3]) + suite.Assert().Equal(float64(ocppj.CALL), parsedFields[0]) + suite.Assert().Equal(mockID, parsedFields[1]) + suite.Assert().Equal(MockFeatureName, parsedFields[2]) + suite.Assert().Equal(mockPayload, parsedFields[3]) return nil }) _ = suite.chargePoint.Start("someUrl") // Trigger incoming invalid CALL err = suite.mockClient.MessageHandler([]byte(invalidMessage)) ocppErr, ok := err.(*ocpp.Error) - require.True(t, ok) - assert.Equal(t, ocppj.FormatErrorType(suite.chargePoint), ocppErr.Code) + suite.Require().True(ok) + suite.Assert().Equal(ocppj.FormatErrorType(suite.chargePoint), ocppErr.Code) // Setup hook 2 mockError := ocpp.NewError(ocppj.InternalError, "custom error", mockID) expectedError = fmt.Sprintf("[4,\"%v\",\"%v\",\"%v\",{}]", mockError.MessageId, mockError.Code, mockError.Description) writeHook.Run(func(args mock.Arguments) { data := args.Get(0).([]byte) - assert.Equal(t, expectedError, string(data)) + suite.Assert().Equal(expectedError, string(data)) }) suite.chargePoint.SetInvalidMessageHook(func(err *ocpp.Error, rawMessage string, parsedFields []interface{}) *ocpp.Error { // Verify the correct fields are passed to the hook. Content is very low-level, since parsing failed - assert.Equal(t, float64(ocppj.CALL), parsedFields[0]) - assert.Equal(t, mockID, parsedFields[1]) - assert.Equal(t, MockFeatureName, parsedFields[2]) - assert.Equal(t, mockPayload, parsedFields[3]) + suite.Assert().Equal(float64(ocppj.CALL), parsedFields[0]) + suite.Assert().Equal(mockID, parsedFields[1]) + suite.Assert().Equal(MockFeatureName, parsedFields[2]) + suite.Assert().Equal(mockPayload, parsedFields[3]) return mockError }) // Trigger incoming invalid CALL that returns custom error err = suite.mockClient.MessageHandler([]byte(invalidMessage)) ocppErr, ok = err.(*ocpp.Error) - require.True(t, ok) - assert.Equal(t, mockError.Code, ocppErr.Code) - assert.Equal(t, mockError.Description, ocppErr.Description) - assert.Equal(t, mockError.MessageId, ocppErr.MessageId) + suite.Require().True(ok) + suite.Assert().Equal(mockError.Code, ocppErr.Code) + suite.Assert().Equal(mockError.Description, ocppErr.Description) + suite.Assert().Equal(mockError.MessageId, ocppErr.MessageId) } func (suite *OcppJTestSuite) TestChargePointSendInvalidCall() { @@ -175,36 +171,34 @@ func (suite *OcppJTestSuite) TestChargePointSendInvalidCall() { // Delete existing profiles and test error suite.chargePoint.Profiles = []*ocpp.Profile{} err := suite.chargePoint.SendRequest(mockRequest) - assert.Error(suite.T(), err, fmt.Sprintf("Couldn't create Call for unsupported action %v", mockRequest.GetFeatureName())) + suite.Assert().Error(err, fmt.Sprintf("Couldn't create Call for unsupported action %v", mockRequest.GetFeatureName())) } func (suite *OcppJTestSuite) TestChargePointSendRequestFailed() { - t := suite.T() var callID string suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(nil) suite.mockClient.On("Write", mock.Anything).Return(fmt.Errorf("networkError")).Run(func(args mock.Arguments) { - require.False(t, suite.clientRequestQueue.IsEmpty()) + suite.Require().False(suite.clientRequestQueue.IsEmpty()) req := suite.clientRequestQueue.Peek().(ocppj.RequestBundle) callID = req.Call.GetUniqueId() _, ok := suite.chargePoint.RequestState.GetPendingRequest(callID) // Before anything is returned, the request must still be pending - assert.True(t, ok) + suite.Assert().True(ok) }) _ = suite.chargePoint.Start("someUrl") mockRequest := newMockRequest("mockValue") err := suite.chargePoint.SendRequest(mockRequest) // TODO: currently the network error is not returned by SendRequest, but is only generated internally - assert.Nil(t, err) + suite.Assert().Nil(err) // Assert that pending request was removed time.Sleep(500 * time.Millisecond) _, ok := suite.chargePoint.RequestState.GetPendingRequest(callID) - assert.False(t, ok) + suite.Assert().False(ok) } // ----------------- SendResponse tests ----------------- func (suite *OcppJTestSuite) TestChargePointSendConfirmation() { - t := suite.T() mockUniqueId := "1234" suite.mockClient.On("Write", mock.Anything).Return(nil) suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(nil) @@ -212,7 +206,7 @@ func (suite *OcppJTestSuite) TestChargePointSendConfirmation() { mockConfirmation := newMockConfirmation("mockValue") // This is allowed. Endpoint doesn't keep track of incoming requests, but only outgoing ones err := suite.chargePoint.SendResponse(mockUniqueId, mockConfirmation) - assert.Nil(t, err) + suite.Assert().Nil(err) } func (suite *OcppJTestSuite) TestChargePointSendConfirmationNoValidation() { @@ -226,11 +220,10 @@ func (suite *OcppJTestSuite) TestChargePointSendConfirmationNoValidation() { defer ocppj.SetMessageValidation(true) // This is allowed. Endpoint doesn't keep track of incoming requests, but only outgoing ones err := suite.chargePoint.SendResponse(mockUniqueId, mockConfirmation) - assert.Nil(suite.T(), err) + suite.Assert().Nil(err) } func (suite *OcppJTestSuite) TestChargePointSendInvalidConfirmation() { - t := suite.T() mockUniqueId := "6789" suite.mockClient.On("Write", mock.Anything).Return(nil) suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(nil) @@ -238,61 +231,56 @@ func (suite *OcppJTestSuite) TestChargePointSendInvalidConfirmation() { mockConfirmation := newMockConfirmation("") // This is allowed. Endpoint doesn't keep track of incoming requests, but only outgoing ones err := suite.chargePoint.SendResponse(mockUniqueId, mockConfirmation) - assert.NotNil(t, err) + suite.Assert().NotNil(err) } func (suite *OcppJTestSuite) TestChargePointSendConfirmationFailed() { - t := suite.T() mockUniqueId := "1234" suite.mockClient.On("Write", mock.Anything).Return(fmt.Errorf("networkError")) suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(nil) _ = suite.chargePoint.Start("someUrl") mockConfirmation := newMockConfirmation("mockValue") err := suite.chargePoint.SendResponse(mockUniqueId, mockConfirmation) - assert.NotNil(t, err) + suite.Assert().NotNil(err) expectedErr := fmt.Sprintf("ocpp message (%v): GenericError - networkError", mockUniqueId) - assert.ErrorContains(t, err, expectedErr) + suite.Assert().ErrorContains(err, expectedErr) } // ----------------- SendError tests ----------------- func (suite *OcppJTestSuite) TestChargePointSendError() { - t := suite.T() mockUniqueId := "1234" mockDescription := "mockDescription" suite.mockClient.On("Write", mock.Anything).Return(nil) err := suite.chargePoint.SendError(mockUniqueId, ocppj.GenericError, mockDescription, nil) - assert.Nil(t, err) + suite.Assert().Nil(err) } func (suite *OcppJTestSuite) TestChargePointSendInvalidError() { - t := suite.T() mockUniqueId := "6789" mockDescription := "mockDescription" suite.mockClient.On("Write", mock.Anything).Return(nil) err := suite.chargePoint.SendError(mockUniqueId, "InvalidErrorCode", mockDescription, nil) - assert.NotNil(t, err) + suite.Assert().NotNil(err) } func (suite *OcppJTestSuite) TestChargePointSendErrorFailed() { - t := suite.T() mockUniqueId := "1234" suite.mockClient.On("Write", mock.Anything).Return(fmt.Errorf("networkError")) mockConfirmation := newMockConfirmation("mockValue") err := suite.chargePoint.SendResponse(mockUniqueId, mockConfirmation) - assert.NotNil(t, err) + suite.Assert().NotNil(err) expectedErr := fmt.Sprintf("ocpp message (%v): GenericError - networkError", mockUniqueId) - assert.ErrorContains(t, err, expectedErr) + suite.Assert().ErrorContains(err, expectedErr) } func (suite *OcppJTestSuite) TestChargePointHandleFailedResponse() { - t := suite.T() msgC := make(chan []byte, 1) mockUniqueID := "1234" suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(nil) suite.mockClient.On("Write", mock.Anything).Return(nil).Run(func(args mock.Arguments) { data, ok := args.Get(0).([]byte) - require.True(t, ok) + suite.Require().True(ok) msgC <- data }) var callResult *ocppj.CallResult @@ -302,102 +290,99 @@ func (suite *OcppJTestSuite) TestChargePointHandleFailedResponse() { mockField := "CallResult.Payload.MockValue" mockResponse := newMockConfirmation("") callResult, err = suite.chargePoint.CreateCallResult(mockResponse, mockUniqueID) - require.Error(t, err) - require.Nil(t, callResult) + suite.Require().Error(err) + suite.Require().Nil(callResult) suite.chargePoint.HandleFailedResponseError(mockUniqueID, err, mockResponse.GetFeatureName()) rawResponse := <-msgC expectedErr := fmt.Sprintf(`[4,"%v","%v","Field %s required but not found for feature %s",{}]`, mockUniqueID, ocppj.OccurrenceConstraintErrorType(suite.chargePoint), mockField, mockResponse.GetFeatureName()) - assert.Equal(t, expectedErr, string(rawResponse)) + suite.Assert().Equal(expectedErr, string(rawResponse)) // 2. property constraint validation error val := "len4" minParamLength := "5" mockResponse = newMockConfirmation(val) callResult, err = suite.chargePoint.CreateCallResult(mockResponse, mockUniqueID) - require.Error(t, err) - require.Nil(t, callResult) + suite.Require().Error(err) + suite.Require().Nil(callResult) suite.chargePoint.HandleFailedResponseError(mockUniqueID, err, mockResponse.GetFeatureName()) rawResponse = <-msgC expectedErr = fmt.Sprintf(`[4,"%v","%v","Field %s must be minimum %s, but was %d for feature %s",{}]`, mockUniqueID, ocppj.PropertyConstraintViolation, mockField, minParamLength, len(val), mockResponse.GetFeatureName()) - assert.Equal(t, expectedErr, string(rawResponse)) + suite.Assert().Equal(expectedErr, string(rawResponse)) // 3. profile not supported mockUnsupportedResponse := &MockUnsupportedResponse{MockValue: "someValue"} callResult, err = suite.chargePoint.CreateCallResult(mockUnsupportedResponse, mockUniqueID) - require.Error(t, err) - require.Nil(t, callResult) + suite.Require().Error(err) + suite.Require().Nil(callResult) suite.chargePoint.HandleFailedResponseError(mockUniqueID, err, mockUnsupportedResponse.GetFeatureName()) rawResponse = <-msgC expectedErr = fmt.Sprintf(`[4,"%v","%v","couldn't create Call Result for unsupported action %s",{}]`, mockUniqueID, ocppj.NotSupported, mockUnsupportedResponse.GetFeatureName()) - assert.Equal(t, expectedErr, string(rawResponse)) + suite.Assert().Equal(expectedErr, string(rawResponse)) // 4. ocpp error validation failed invalidErrorCode := "InvalidErrorCode" callError, err = suite.chargePoint.CreateCallError(mockUniqueID, ocpp.ErrorCode(invalidErrorCode), "", nil) - require.Error(t, err) - require.Nil(t, callError) + suite.Require().Error(err) + suite.Require().Nil(callError) suite.chargePoint.HandleFailedResponseError(mockUniqueID, err, "") rawResponse = <-msgC expectedErr = fmt.Sprintf(`[4,"%v","%v","Key: 'CallError.ErrorCode' Error:Field validation for 'ErrorCode' failed on the 'errorCode' tag",{}]`, mockUniqueID, ocppj.GenericError) - assert.Equal(t, expectedErr, string(rawResponse)) + suite.Assert().Equal(expectedErr, string(rawResponse)) // 5. marshaling err err = suite.chargePoint.SendError(mockUniqueID, ocppj.SecurityError, "", make(chan struct{})) - require.Error(t, err) + suite.Require().Error(err) suite.chargePoint.HandleFailedResponseError(mockUniqueID, err, "") rawResponse = <-msgC expectedErr = fmt.Sprintf(`[4,"%v","%v","json: unsupported type: chan struct {}",{}]`, mockUniqueID, ocppj.GenericError) - assert.Equal(t, expectedErr, string(rawResponse)) + suite.Assert().Equal(expectedErr, string(rawResponse)) // 6. network error rawErr := "client is currently not connected, cannot send data" err = ocpp.NewError(ocppj.GenericError, rawErr, mockUniqueID) suite.chargePoint.HandleFailedResponseError(mockUniqueID, err, "") rawResponse = <-msgC expectedErr = fmt.Sprintf(`[4,"%v","%v","%s",{}]`, mockUniqueID, ocppj.GenericError, rawErr) - assert.Equal(t, expectedErr, string(rawResponse)) + suite.Assert().Equal(expectedErr, string(rawResponse)) } // ----------------- Call Handlers tests ----------------- func (suite *OcppJTestSuite) TestChargePointCallHandler() { - t := suite.T() mockUniqueId := "5678" mockValue := "someValue" mockRequest := fmt.Sprintf(`[2,"%v","%v",{"mockValue":"%v"}]`, mockUniqueId, MockFeatureName, mockValue) suite.chargePoint.SetRequestHandler(func(request ocpp.Request, requestId string, action string) { - assert.Equal(t, mockUniqueId, requestId) - assert.Equal(t, MockFeatureName, action) - assert.NotNil(t, request) + suite.Assert().Equal(mockUniqueId, requestId) + suite.Assert().Equal(MockFeatureName, action) + suite.Assert().NotNil(request) }) suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(nil).Run(func(args mock.Arguments) { // Simulate central system message err := suite.mockClient.MessageHandler([]byte(mockRequest)) - assert.Nil(t, err) + suite.Assert().Nil(err) }) err := suite.chargePoint.Start("somePath") - assert.Nil(t, err) + suite.Assert().Nil(err) } func (suite *OcppJTestSuite) TestChargePointCallResultHandler() { - t := suite.T() mockUniqueId := "5678" mockValue := "someValue" mockRequest := newMockRequest("testValue") mockConfirmation := fmt.Sprintf(`[3,"%v",{"mockValue":"%v"}]`, mockUniqueId, mockValue) suite.chargePoint.SetResponseHandler(func(confirmation ocpp.Response, requestId string) { - assert.Equal(t, mockUniqueId, requestId) - assert.NotNil(t, confirmation) + suite.Assert().Equal(mockUniqueId, requestId) + suite.Assert().NotNil(confirmation) }) suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(nil) suite.chargePoint.RequestState.AddPendingRequest(mockUniqueId, mockRequest) // Manually add a pending request, so that response is not rejected err := suite.chargePoint.Start("somePath") - assert.Nil(t, err) + suite.Assert().Nil(err) // Simulate central system message err = suite.mockClient.MessageHandler([]byte(mockConfirmation)) - assert.Nil(t, err) + suite.Assert().Nil(err) } func (suite *OcppJTestSuite) TestChargePointCallErrorHandler() { - t := suite.T() mockUniqueId := "5678" mockErrorCode := ocppj.GenericError mockErrorDescription := "Mock Description" @@ -408,50 +393,48 @@ func (suite *OcppJTestSuite) TestChargePointCallErrorHandler() { mockRequest := newMockRequest("testValue") mockError := fmt.Sprintf(`[4,"%v","%v","%v",{"details":"%v"}]`, mockUniqueId, mockErrorCode, mockErrorDescription, mockValue) suite.chargePoint.SetErrorHandler(func(err *ocpp.Error, details interface{}) { - assert.Equal(t, mockUniqueId, err.MessageId) - assert.Equal(t, mockErrorCode, err.Code) - assert.Equal(t, mockErrorDescription, err.Description) - assert.Equal(t, mockErrorDetails, details) + suite.Assert().Equal(mockUniqueId, err.MessageId) + suite.Assert().Equal(mockErrorCode, err.Code) + suite.Assert().Equal(mockErrorDescription, err.Description) + suite.Assert().Equal(mockErrorDetails, details) }) suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(nil) suite.chargePoint.RequestState.AddPendingRequest(mockUniqueId, mockRequest) // Manually add a pending request, so that response is not rejected err := suite.chargePoint.Start("someUrl") - assert.Nil(t, err) + suite.Assert().Nil(err) // Simulate central system message err = suite.mockClient.MessageHandler([]byte(mockError)) - assert.Nil(t, err) + suite.Assert().Nil(err) } // ----------------- Queue processing tests ----------------- func (suite *OcppJTestSuite) TestClientEnqueueRequest() { - t := suite.T() suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(nil) suite.mockClient.On("Write", mock.Anything).Return(nil) // Start normally err := suite.chargePoint.Start("someUrl") - require.Nil(t, err) + suite.Require().Nil(err) req := newMockRequest("somevalue") err = suite.chargePoint.SendRequest(req) - require.Nil(t, err) + suite.Require().Nil(err) time.Sleep(500 * time.Millisecond) // Message was sent, but element should still be in queue - require.False(t, suite.clientRequestQueue.IsEmpty()) - assert.Equal(t, 1, suite.clientRequestQueue.Size()) + suite.Require().False(suite.clientRequestQueue.IsEmpty()) + suite.Assert().Equal(1, suite.clientRequestQueue.Size()) // Analyze enqueued bundle peeked := suite.clientRequestQueue.Peek() - require.NotNil(t, peeked) + suite.Require().NotNil(peeked) bundle, ok := peeked.(ocppj.RequestBundle) - require.True(t, ok) - require.NotNil(t, bundle) - assert.Equal(t, req.GetFeatureName(), bundle.Call.Action) + suite.Require().True(ok) + suite.Require().NotNil(bundle) + suite.Assert().Equal(req.GetFeatureName(), bundle.Call.Action) marshaled, err := bundle.Call.MarshalJSON() - require.Nil(t, err) - assert.Equal(t, marshaled, bundle.Data) + suite.Require().Nil(err) + suite.Assert().Equal(marshaled, bundle.Data) } func (suite *OcppJTestSuite) TestClientEnqueueMultipleRequests() { - t := suite.T() messagesToQueue := 5 sentMessages := 0 suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(nil) @@ -460,53 +443,51 @@ func (suite *OcppJTestSuite) TestClientEnqueueMultipleRequests() { }).Return(nil) // Start normally err := suite.chargePoint.Start("someUrl") - require.Nil(t, err) + suite.Require().Nil(err) for i := 0; i < messagesToQueue; i++ { req := newMockRequest(fmt.Sprintf("request-%v", i)) err = suite.chargePoint.SendRequest(req) - require.Nil(t, err) + suite.Require().Nil(err) } time.Sleep(500 * time.Millisecond) // Only one message was sent, but all elements should still be in queue - assert.Equal(t, 1, sentMessages) - require.False(t, suite.clientRequestQueue.IsEmpty()) - assert.Equal(t, messagesToQueue, suite.clientRequestQueue.Size()) + suite.Assert().Equal(1, sentMessages) + suite.Require().False(suite.clientRequestQueue.IsEmpty()) + suite.Assert().Equal(messagesToQueue, suite.clientRequestQueue.Size()) // Analyze enqueued bundle var i int for !suite.clientRequestQueue.IsEmpty() { popped := suite.clientRequestQueue.Pop() - require.NotNil(t, popped) + suite.Require().NotNil(popped) bundle, ok := popped.(ocppj.RequestBundle) - require.True(t, ok) - require.NotNil(t, bundle) - assert.Equal(t, MockFeatureName, bundle.Call.Action) + suite.Require().True(ok) + suite.Require().NotNil(bundle) + suite.Assert().Equal(MockFeatureName, bundle.Call.Action) i++ } - assert.Equal(t, messagesToQueue, i) + suite.Assert().Equal(messagesToQueue, i) } func (suite *OcppJTestSuite) TestClientRequestQueueFull() { - t := suite.T() messagesToQueue := queueCapacity suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(nil) suite.mockClient.On("Write", mock.Anything).Return(nil) // Start normally err := suite.chargePoint.Start("someUrl") - require.Nil(t, err) + suite.Require().Nil(err) for i := 0; i < messagesToQueue; i++ { req := newMockRequest(fmt.Sprintf("request-%v", i)) err = suite.chargePoint.SendRequest(req) - require.Nil(t, err) + suite.Require().Nil(err) } // Queue is now full. Trying to send an additional message should throw an error req := newMockRequest("full") err = suite.chargePoint.SendRequest(req) - require.NotNil(t, err) - assert.Equal(t, "request queue is full, cannot push new element", err.Error()) + suite.Require().NotNil(err) + suite.Assert().Equal("request queue is full, cannot push new element", err.Error()) } func (suite *OcppJTestSuite) TestClientParallelRequests() { - t := suite.T() messagesToQueue := 10 sentMessages := 0 suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(nil) @@ -515,18 +496,18 @@ func (suite *OcppJTestSuite) TestClientParallelRequests() { }).Return(nil) // Start normally err := suite.chargePoint.Start("someUrl") - require.Nil(t, err) + suite.Require().Nil(err) for i := 0; i < messagesToQueue; i++ { go func() { req := newMockRequest("someReq") err = suite.chargePoint.SendRequest(req) - require.Nil(t, err) + suite.Require().Nil(err) }() } time.Sleep(1000 * time.Millisecond) // Only one message was sent, but all element should still be in queue - require.False(t, suite.clientRequestQueue.IsEmpty()) - assert.Equal(t, messagesToQueue, suite.clientRequestQueue.Size()) + suite.Require().False(suite.clientRequestQueue.IsEmpty()) + suite.Assert().Equal(messagesToQueue, suite.clientRequestQueue.Size()) } // TestClientRequestFlow tests a typical flow with multiple request-responses. @@ -543,7 +524,7 @@ func (suite *OcppJTestSuite) TestClientRequestFlow() { suite.mockClient.On("Write", mock.Anything).Run(func(args mock.Arguments) { data := args.Get(0).([]byte) call := ParseCall(&suite.chargePoint.Endpoint, suite.chargePoint.RequestState, string(data), t) - require.NotNil(t, call) + suite.Require().NotNil(call) sendResponseTrigger <- call }).Return(nil) // Mocked response generator @@ -559,8 +540,8 @@ func (suite *OcppJTestSuite) TestClientRequestFlow() { // Get original request to generate meaningful response peeked := suite.clientRequestQueue.Peek() bundle, _ := peeked.(ocppj.RequestBundle) - require.NotNil(t, bundle) - assert.Equal(t, call.UniqueId, bundle.Call.UniqueId) + suite.Require().NotNil(bundle) + suite.Assert().Equal(call.UniqueId, bundle.Call.UniqueId) req, _ := call.Payload.(*MockRequest) // Send response back to client var data []byte @@ -570,27 +551,27 @@ func (suite *OcppJTestSuite) TestClientRequestFlow() { // Send CallResult resp := newMockConfirmation("someResp") res, err := suite.chargePoint.CreateCallResult(resp, call.GetUniqueId()) - require.Nil(t, err) + suite.Require().Nil(err) data, err = res.MarshalJSON() - require.Nil(t, err) + suite.Require().Nil(err) } else { // Send CallError res, err := suite.chargePoint.CreateCallError(call.GetUniqueId(), ocppj.GenericError, fmt.Sprintf("error-%v", req.MockValue), nil) - require.Nil(t, err) + suite.Require().Nil(err) data, err = res.MarshalJSON() - require.Nil(t, err) + suite.Require().Nil(err) } fmt.Printf("sending mocked response to message %v\n", call.GetUniqueId()) err = suite.mockClient.MessageHandler(data) // Triggers ocppMessageHandler - require.Nil(t, err) + suite.Require().Nil(err) // Make sure the top queue element was popped mutex.Lock() processedMessages += 1 peeked = suite.clientRequestQueue.Peek() if peeked != nil { bundle, _ := peeked.(ocppj.RequestBundle) - require.NotNil(t, bundle) - assert.NotEqual(t, call.UniqueId, bundle.Call.UniqueId) + suite.Require().NotNil(bundle) + suite.Assert().NotEqual(call.UniqueId, bundle.Call.UniqueId) } mutex.Unlock() wg.Done() @@ -598,18 +579,18 @@ func (suite *OcppJTestSuite) TestClientRequestFlow() { }() // Start client normally err := suite.chargePoint.Start("someUrl") - require.Nil(t, err) + suite.Require().Nil(err) for i := 0; i < messagesToQueue; i++ { go func(j int) { req := newMockRequest(fmt.Sprintf("%v", j)) - err = suite.chargePoint.SendRequest(req) - require.Nil(t, err) + err := suite.chargePoint.SendRequest(req) + suite.Require().Nil(err) }(i) } // Wait for processing to complete wg.Wait() close(sendResponseTrigger) - assert.True(t, suite.clientRequestQueue.IsEmpty()) + suite.Assert().True(suite.clientRequestQueue.IsEmpty()) } // TestClientDisconnected ensures that upon disconnection, the client keeps its internal state @@ -626,12 +607,12 @@ func (suite *OcppJTestSuite) TestClientDisconnected() { sentMessages += 1 data := args.Get(0).([]byte) call := ParseCall(&suite.chargePoint.Endpoint, suite.chargePoint.RequestState, string(data), t) - require.NotNil(t, call) + suite.Require().NotNil(call) writeC <- call }).Return(nil) // Start normally err := suite.chargePoint.Start("someUrl") - require.Nil(t, err) + suite.Require().Nil(err) // Start mocked response routine go func() { counter := 0 @@ -653,26 +634,26 @@ func (suite *OcppJTestSuite) TestClientDisconnected() { for i := 0; i < messagesToQueue; i++ { req := newMockRequest(fmt.Sprintf("%v", i)) err = suite.chargePoint.SendRequest(req) - require.NoError(t, err) + suite.Require().NoError(err) } // Wait for trigger disconnect after a few responses were returned <-triggerC - assert.False(t, suite.clientDispatcher.IsPaused()) + suite.Assert().False(suite.clientDispatcher.IsPaused()) suite.mockClient.DisconnectedHandler(disconnectError) time.Sleep(200 * time.Millisecond) // Not all messages were sent, some are still in queue - assert.True(t, suite.clientDispatcher.IsPaused()) - assert.True(t, suite.clientDispatcher.IsRunning()) + suite.Assert().True(suite.clientDispatcher.IsPaused()) + suite.Assert().True(suite.clientDispatcher.IsRunning()) currentSize := suite.clientRequestQueue.Size() currentSent := sentMessages // Wait for some more time and double-check time.Sleep(500 * time.Millisecond) - assert.True(t, suite.clientDispatcher.IsPaused()) - assert.True(t, suite.clientDispatcher.IsRunning()) - assert.Equal(t, currentSize, suite.clientRequestQueue.Size()) - assert.Equal(t, currentSent, sentMessages) - assert.Less(t, currentSize, messagesToQueue) - assert.Less(t, sentMessages, messagesToQueue) + suite.Assert().True(suite.clientDispatcher.IsPaused()) + suite.Assert().True(suite.clientDispatcher.IsRunning()) + suite.Assert().Equal(currentSize, suite.clientRequestQueue.Size()) + suite.Assert().Equal(currentSent, sentMessages) + suite.Assert().Less(currentSize, messagesToQueue) + suite.Assert().Less(sentMessages, messagesToQueue) } // TestClientReconnected ensures that upon reconnection, the client retains its internal state @@ -689,14 +670,14 @@ func (suite *OcppJTestSuite) TestClientReconnected() { sentMessages += 1 data := args.Get(0).([]byte) call := ParseCall(&suite.chargePoint.Endpoint, suite.chargePoint.RequestState, string(data), t) - require.NotNil(t, call) + suite.Require().NotNil(call) writeC <- call }).Return(nil) isConnectedCall := suite.mockClient.On("IsConnected").Return(true) // Start normally err := suite.chargePoint.Start("someUrl") - require.Nil(t, err) - assert.True(t, suite.chargePoint.IsConnected()) + suite.Require().Nil(err) + suite.Assert().True(suite.chargePoint.IsConnected()) // Start mocked response routine go func() { counter := 0 @@ -716,12 +697,12 @@ func (suite *OcppJTestSuite) TestClientReconnected() { }() // Get the pending request state struct state := suite.chargePoint.RequestState - assert.False(t, state.HasPendingRequest()) + suite.Assert().False(state.HasPendingRequest()) // Send some messages for i := 0; i < messagesToQueue; i++ { req := newMockRequest(fmt.Sprintf("%v", i)) err = suite.chargePoint.SendRequest(req) - require.NoError(t, err) + suite.Require().NoError(err) } // Wait for trigger disconnect after a few responses were returned <-triggerC @@ -729,24 +710,24 @@ func (suite *OcppJTestSuite) TestClientReconnected() { suite.mockClient.DisconnectedHandler(disconnectError) // One message was sent, but all others are still in queue time.Sleep(200 * time.Millisecond) - assert.True(t, suite.clientDispatcher.IsPaused()) - assert.False(t, suite.chargePoint.IsConnected()) + suite.Assert().True(suite.clientDispatcher.IsPaused()) + suite.Assert().False(suite.chargePoint.IsConnected()) // Wait for some more time and then reconnect time.Sleep(500 * time.Millisecond) isConnectedCall.Return(true) suite.mockClient.ReconnectedHandler() - assert.False(t, suite.clientDispatcher.IsPaused()) - assert.True(t, suite.clientDispatcher.IsRunning()) - assert.False(t, suite.clientRequestQueue.IsEmpty()) - assert.True(t, suite.chargePoint.IsConnected()) + suite.Assert().False(suite.clientDispatcher.IsPaused()) + suite.Assert().True(suite.clientDispatcher.IsRunning()) + suite.Assert().False(suite.clientRequestQueue.IsEmpty()) + suite.Assert().True(suite.chargePoint.IsConnected()) // Wait until remaining messages are sent <-triggerC - assert.False(t, suite.clientDispatcher.IsPaused()) - assert.True(t, suite.clientDispatcher.IsRunning()) - assert.Equal(t, messagesToQueue, sentMessages) - assert.True(t, suite.clientRequestQueue.IsEmpty()) - assert.False(t, state.HasPendingRequest()) - assert.True(t, suite.chargePoint.IsConnected()) + suite.Assert().False(suite.clientDispatcher.IsPaused()) + suite.Assert().True(suite.clientDispatcher.IsRunning()) + suite.Assert().Equal(messagesToQueue, sentMessages) + suite.Assert().True(suite.clientRequestQueue.IsEmpty()) + suite.Assert().False(state.HasPendingRequest()) + suite.Assert().True(suite.chargePoint.IsConnected()) } // TestClientResponseTimeout ensures that upon a response timeout, the client dispatcher: @@ -762,65 +743,64 @@ func (suite *OcppJTestSuite) TestClientResponseTimeout() { suite.mockClient.On("Write", mock.Anything).Run(func(args mock.Arguments) { data := args.Get(0).([]byte) call := ParseCall(&suite.chargePoint.Endpoint, suite.chargePoint.RequestState, string(data), t) - require.NotNil(t, call) + suite.Require().NotNil(call) requestID = call.UniqueId }).Return(nil) suite.clientDispatcher.SetOnRequestCanceled(func(rID string, request ocpp.Request, err *ocpp.Error) { - assert.Equal(t, requestID, rID) - assert.Equal(t, MockFeatureName, request.GetFeatureName()) - assert.Equal(t, req, request) - assert.Error(t, err) + suite.Assert().Equal(requestID, rID) + suite.Assert().Equal(MockFeatureName, request.GetFeatureName()) + suite.Assert().Equal(req, request) + suite.Assert().Error(err) timeoutC <- true }) // Sets a low response timeout for testing purposes suite.clientDispatcher.SetTimeout(500 * time.Millisecond) // Start normally and send a message err := suite.chargePoint.Start("someUrl") - require.NoError(t, err) + suite.Require().NoError(err) err = suite.chargePoint.SendRequest(req) - require.NoError(t, err) + suite.Require().NoError(err) // Wait for request to be enqueued, then check state time.Sleep(50 * time.Millisecond) state := suite.chargePoint.RequestState - assert.False(t, suite.clientRequestQueue.IsEmpty()) - assert.True(t, suite.clientDispatcher.IsRunning()) - assert.Equal(t, 1, suite.clientRequestQueue.Size()) - assert.True(t, state.HasPendingRequest()) + suite.Assert().False(suite.clientRequestQueue.IsEmpty()) + suite.Assert().True(suite.clientDispatcher.IsRunning()) + suite.Assert().Equal(1, suite.clientRequestQueue.Size()) + suite.Assert().True(state.HasPendingRequest()) // Wait for timeout error to be thrown <-timeoutC - assert.True(t, suite.clientRequestQueue.IsEmpty()) - assert.True(t, suite.clientDispatcher.IsRunning()) - assert.False(t, state.HasPendingRequest()) + suite.Assert().True(suite.clientRequestQueue.IsEmpty()) + suite.Assert().True(suite.clientDispatcher.IsRunning()) + suite.Assert().False(state.HasPendingRequest()) } func (suite *OcppJTestSuite) TestStopDisconnectedClient() { - t := suite.T() suite.mockClient.On("Start", mock.AnythingOfType("string")).Return(nil) suite.mockClient.On("Write", mock.Anything).Return(nil) suite.mockClient.On("Stop").Return(nil) call := suite.mockClient.On("IsConnected").Return(true) // Start normally err := suite.chargePoint.Start("someUrl") - require.NoError(t, err) + suite.Require().NoError(err) // Trigger network disconnect disconnectError := fmt.Errorf("some error") suite.chargePoint.SetOnDisconnectedHandler(func(err error) { - require.Errorf(t, err, disconnectError.Error()) + suite.Require().Errorf(err, disconnectError.Error()) }) call.Return(false) suite.mockClient.DisconnectedHandler(disconnectError) time.Sleep(100 * time.Millisecond) // Dispatcher should be paused - assert.True(t, suite.clientDispatcher.IsPaused()) - assert.False(t, suite.chargePoint.IsConnected()) + suite.Assert().True(suite.clientDispatcher.IsPaused()) + suite.Assert().False(suite.chargePoint.IsConnected()) // Stop client while reconnecting suite.chargePoint.Stop() time.Sleep(50 * time.Millisecond) - assert.True(t, suite.clientDispatcher.IsPaused()) - assert.False(t, suite.chargePoint.IsConnected()) + suite.Assert().True(suite.clientDispatcher.IsPaused()) + suite.Assert().False(suite.chargePoint.IsConnected()) // Attempt stopping client again suite.chargePoint.Stop() time.Sleep(50 * time.Millisecond) - assert.True(t, suite.clientDispatcher.IsPaused()) - assert.False(t, suite.chargePoint.IsConnected()) + suite.Assert().True(suite.clientDispatcher.IsPaused()) + suite.Assert().False(suite.chargePoint.IsConnected()) } diff --git a/ocppj/client.go b/ocppj/client.go index ff2fc18c..ee9eef8d 100644 --- a/ocppj/client.go +++ b/ocppj/client.go @@ -6,14 +6,16 @@ import ( "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ws" + "github.com/xBlaz3kx/ocpp-go/logging" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ws" ) // The endpoint initiating the connection to an OCPP server, in an OCPP-J topology. // During message exchange, the two roles may be reversed (depending on the message direction), but a client struct remains associated to a charge point/charging station. type Client struct { Endpoint + logger logging.Logger client ws.Client Id string requestHandler func(request ocpp.Request, requestId string, action string) @@ -28,31 +30,50 @@ type Client struct { // Creates a new Client endpoint. // Requires a unique client ID, a websocket client, a struct for queueing/dispatching requests, -// a state handler and a list of supported profiles (optional). +// a state handler, a logger, and a list of supported profiles (optional). // -// You may create a simple new server by using these default values: +// You may create a simple new client by using these default values: // -// s := ocppj.NewClient(ws.NewClient(), nil, nil) +// c := ocppj.NewClient("client_id", ws.NewClient(), nil, nil, nil) // // The wsClient parameter cannot be nil. Refer to the ws package for information on how to create and -// customize a websocket client. -func NewClient(id string, wsClient ws.Client, dispatcher ClientDispatcher, stateHandler ClientState, profiles ...*ocpp.Profile) *Client { +// customize a websocket client. If logger is nil, a VoidLogger will be used. +func NewClient(id string, wsClient ws.Client, dispatcher ClientDispatcher, stateHandler ClientState, logger logging.Logger, profiles ...*ocpp.Profile) (*Client, error) { endpoint := Endpoint{} - if wsClient == nil { - panic("wsClient parameter cannot be nil") - } for _, profile := range profiles { endpoint.AddProfile(profile) } + + if wsClient == nil { + return nil, errors.New("ws client cannot be nil") + } + + // Create a void logger if none is provided + if logger == nil { + logger = &logging.VoidLogger{} + } + + // Create a default dispatcher if none is provided if dispatcher == nil { - dispatcher = NewDefaultClientDispatcher(NewFIFOClientQueue(10)) + dispatcher = NewDefaultClientDispatcher(NewFIFOClientQueue(10), logger) } + + // Create a default state handler if none is provided if stateHandler == nil { stateHandler = NewClientState() } + dispatcher.SetNetworkClient(wsClient) dispatcher.SetPendingRequestState(stateHandler) - return &Client{Endpoint: endpoint, client: wsClient, Id: id, dispatcher: dispatcher, RequestState: stateHandler} + + return &Client{ + Endpoint: endpoint, + logger: logger, + client: wsClient, + Id: id, + dispatcher: dispatcher, + RequestState: stateHandler, + }, nil } // Return incoming requests handler. @@ -201,10 +222,10 @@ func (c *Client) SendRequest(request ocpp.Request) error { } // Message will be processed by dispatcher. A dedicated mechanism allows to delegate the message queue handling. if err = c.dispatcher.SendRequest(RequestBundle{Call: call, Data: jsonMessage}); err != nil { - log.Errorf("error dispatching request [%s, %s]: %v", call.UniqueId, call.Action, err) + c.logger.Errorf("error dispatching request [%s, %s]: %v", call.UniqueId, call.Action, err) return err } - log.Debugf("enqueued CALL [%s, %s]", call.UniqueId, call.Action) + c.logger.Debugf("enqueued CALL [%s, %s]", call.UniqueId, call.Action) return nil } @@ -228,11 +249,11 @@ func (c *Client) SendResponse(requestId string, response ocpp.Response) error { return ocpp.NewError(GenericError, err.Error(), requestId) } if err = c.client.Write(jsonMessage); err != nil { - log.Errorf("error sending response [%s]: %v", callResult.GetUniqueId(), err) + c.logger.Errorf("error sending response [%s]: %v", callResult.GetUniqueId(), err) return ocpp.NewError(GenericError, err.Error(), requestId) } - log.Debugf("sent CALL RESULT [%s]", callResult.GetUniqueId()) - log.Debugf("sent JSON message to server: %s", string(jsonMessage)) + c.logger.Debugf("sent CALL RESULT [%s]", callResult.GetUniqueId()) + c.logger.Debugf("sent JSON message to server: %s", string(jsonMessage)) return nil } @@ -254,21 +275,21 @@ func (c *Client) SendError(requestId string, errorCode ocpp.ErrorCode, descripti return ocpp.NewError(GenericError, err.Error(), requestId) } if err = c.client.Write(jsonMessage); err != nil { - log.Errorf("error sending response error [%s]: %v", callError.UniqueId, err) + c.logger.Errorf("error sending response error [%s]: %v", callError.UniqueId, err) return ocpp.NewError(GenericError, err.Error(), requestId) } - log.Debugf("sent CALL ERROR [%s]", callError.UniqueId) - log.Debugf("sent JSON message to server: %s", string(jsonMessage)) + c.logger.Debugf("sent CALL ERROR [%s]", callError.UniqueId) + c.logger.Debugf("sent JSON message to server: %s", string(jsonMessage)) return nil } func (c *Client) ocppMessageHandler(data []byte) error { parsedJson, err := ParseRawJsonMessage(data) if err != nil { - log.Error(err) + c.logger.Error(err) return err } - log.Debugf("received JSON message from server: %s", string(data)) + c.logger.Debugf("received JSON message from server: %s", string(data)) message, err := c.ParseMessage(parsedJson, c.RequestState) if err != nil { ocppErr := err.(*ocpp.Error) @@ -290,25 +311,25 @@ func (c *Client) ocppMessageHandler(data []byte) error { return err2 } } - log.Error(err) + c.logger.Error(err) return err } if message != nil { switch message.GetMessageTypeId() { case CALL: call := message.(*Call) - log.Debugf("handling incoming CALL [%s, %s]", call.UniqueId, call.Action) + c.logger.Debugf("handling incoming CALL [%s, %s]", call.UniqueId, call.Action) c.requestHandler(call.Payload, call.UniqueId, call.Action) case CALL_RESULT: callResult := message.(*CallResult) - log.Debugf("handling incoming CALL RESULT [%s]", callResult.UniqueId) + c.logger.Debugf("handling incoming CALL RESULT [%s]", callResult.UniqueId) c.dispatcher.CompleteRequest(callResult.GetUniqueId()) // Remove current request from queue and send next one if c.responseHandler != nil { c.responseHandler(callResult.Payload, callResult.UniqueId) } case CALL_ERROR: callError := message.(*CallError) - log.Debugf("handling incoming CALL ERROR [%s]", callError.UniqueId) + c.logger.Debugf("handling incoming CALL ERROR [%s]", callError.UniqueId) c.dispatcher.CompleteRequest(callError.GetUniqueId()) // Remove current request from queue and send next one if c.errorHandler != nil { c.errorHandler(ocpp.NewError(callError.ErrorCode, callError.ErrorDescription, callError.UniqueId), callError.ErrorDetails) @@ -326,7 +347,7 @@ func (c *Client) ocppMessageHandler(data []byte) error { // The method will, however, only attempt to send a default error once. // If this operation fails, the other endpoint may still starve. func (c *Client) HandleFailedResponseError(requestID string, err error, featureName string) { - log.Debugf("handling error for failed response [%s]", requestID) + c.logger.Debugf("handling error for failed response [%s]", requestID) var responseErr *ocpp.Error // There's several possible errors: invalid profile, invalid payload or send error switch err.(type) { @@ -347,7 +368,7 @@ func (c *Client) HandleFailedResponseError(requestID string, err error, featureN } func (c *Client) onDisconnected(err error) { - log.Error("disconnected from server", err) + c.logger.Error("disconnected from server", err) c.dispatcher.Pause() if c.onDisconnectedHandler != nil { c.onDisconnectedHandler(err) diff --git a/ocppj/dispatcher.go b/ocppj/dispatcher.go index f27cf6bd..f2ac690e 100644 --- a/ocppj/dispatcher.go +++ b/ocppj/dispatcher.go @@ -2,12 +2,17 @@ package ocppj import ( "context" + "errors" "fmt" "sync" + "sync/atomic" "time" - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ws" + "go.opentelemetry.io/otel/metric" + + "github.com/xBlaz3kx/ocpp-go/logging" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ws" ) // ClientDispatcher contains the state and logic for handling outgoing messages on a client endpoint. @@ -86,6 +91,7 @@ type pendingRequest struct { // The dispatcher implements the ClientState as well for simplicity. // Access to pending requests is thread-safe. type DefaultClientDispatcher struct { + logger logging.Logger requestQueue RequestQueue requestChannel chan bool readyForDispatch chan bool @@ -94,7 +100,7 @@ type DefaultClientDispatcher struct { mutex sync.RWMutex onRequestCancel func(requestID string, request ocpp.Request, err *ocpp.Error) timer *time.Timer - paused bool + paused atomic.Bool timeout time.Duration } @@ -104,8 +110,13 @@ const ( ) // NewDefaultClientDispatcher creates a new DefaultClientDispatcher struct. -func NewDefaultClientDispatcher(queue RequestQueue) *DefaultClientDispatcher { +// If logger is nil, a VoidLogger will be used. +func NewDefaultClientDispatcher(queue RequestQueue, logger logging.Logger) *DefaultClientDispatcher { + if logger == nil { + logger = &logging.VoidLogger{} + } return &DefaultClientDispatcher{ + logger: logger, requestQueue: queue, requestChannel: nil, readyForDispatch: make(chan bool, 1), @@ -124,9 +135,10 @@ func (d *DefaultClientDispatcher) SetTimeout(timeout time.Duration) { func (d *DefaultClientDispatcher) Start() { d.mutex.Lock() - defer d.mutex.Unlock() d.requestChannel = make(chan bool, 1) d.timer = time.NewTimer(defaultTimeoutTick) // Default to 24 hours tick + d.mutex.Unlock() + go d.messagePump() } @@ -137,14 +149,13 @@ func (d *DefaultClientDispatcher) IsRunning() bool { } func (d *DefaultClientDispatcher) IsPaused() bool { - d.mutex.RLock() - defer d.mutex.RUnlock() - return d.paused + return d.paused.Load() } func (d *DefaultClientDispatcher) Stop() { d.mutex.Lock() defer d.mutex.Unlock() + close(d.requestChannel) // TODO: clear pending requests? } @@ -165,23 +176,20 @@ func (d *DefaultClientDispatcher) SendRequest(req RequestBundle) error { return err } d.mutex.RLock() - d.requestChannel <- true + if d.requestChannel != nil { + d.requestChannel <- true + } d.mutex.RUnlock() + return nil } func (d *DefaultClientDispatcher) messagePump() { rdy := true // Ready to transmit at the beginning - reqChan := func() chan bool { - d.mutex.RLock() - defer d.mutex.RUnlock() - return d.requestChannel - } - for { select { - case _, ok := <-reqChan(): + case _, ok := <-d.requestChannel: // New request was posted if !ok { d.requestQueue.Init() @@ -246,8 +254,8 @@ func (d *DefaultClientDispatcher) dispatchNextRequest() { ocpp.NewError(InternalError, err.Error(), bundle.Call.UniqueId)) } } - log.Infof("dispatched request %s to server", bundle.Call.UniqueId) - log.Debugf("sent JSON message to server: %s", string(jsonMessage)) + d.logger.Infof("dispatched request %s to server", bundle.Call.UniqueId) + d.logger.Debugf("sent JSON message to server: %s", string(jsonMessage)) } func (d *DefaultClientDispatcher) Pause() { @@ -256,14 +264,13 @@ func (d *DefaultClientDispatcher) Pause() { if !d.timer.Stop() { <-d.timer.C } + d.timer.Reset(defaultTimeoutTick) - d.paused = true + d.paused.Store(true) } func (d *DefaultClientDispatcher) Resume() { - d.mutex.Lock() - d.paused = false - d.mutex.Unlock() + d.paused.Store(false) if d.pendingRequestState.HasPendingRequest() { // There is a pending request already. Awaiting response, before dispatching new requests. d.timer.Reset(d.timeout) @@ -276,17 +283,17 @@ func (d *DefaultClientDispatcher) Resume() { func (d *DefaultClientDispatcher) CompleteRequest(requestId string) { el := d.requestQueue.Peek() if el == nil { - log.Errorf("attempting to pop front of queue, but queue is empty") + d.logger.Errorf("attempting to pop front of queue, but queue is empty") return } bundle, _ := el.(RequestBundle) if bundle.Call.UniqueId != requestId { - log.Errorf("internal state mismatch: received response for %v but expected response for %v", requestId, bundle.Call.UniqueId) + d.logger.Errorf("internal state mismatch: received response for %v but expected response for %v", requestId, bundle.Call.UniqueId) return } d.requestQueue.Pop() d.pendingRequestState.DeletePendingRequest(requestId) - log.Debugf("removed request %v from front of queue", bundle.Call.UniqueId) + d.logger.Debugf("removed request %v from front of queue", bundle.Call.UniqueId) // Signal that next message in queue may be sent d.readyForDispatch <- true } @@ -362,17 +369,19 @@ type ServerDispatcher interface { // The dispatcher implements the ClientState as well for simplicity. // Access to pending requests is thread-safe. type DefaultServerDispatcher struct { + logger logging.Logger queueMap ServerQueueMap requestChannel chan string readyForDispatch chan string pendingRequestState ServerState timeout time.Duration timerC chan string - running bool + running atomic.Bool stoppedC chan struct{} onRequestCancel CanceledRequestHandler network ws.Server mutex sync.RWMutex + metrics *dispatcherMetrics } // Handler function to be invoked when a request gets canceled (either due to timeout or to other external factors). @@ -389,38 +398,60 @@ func (c clientTimeoutContext) isActive() bool { } // NewDefaultServerDispatcher creates a new DefaultServerDispatcher struct. -func NewDefaultServerDispatcher(queueMap ServerQueueMap) *DefaultServerDispatcher { +// If logger is nil, a VoidLogger will be used. +func NewDefaultServerDispatcher(queueMap ServerQueueMap, provider metric.MeterProvider, logger logging.Logger) *DefaultServerDispatcher { + if logger == nil { + logger = &logging.VoidLogger{} + } + + dispatcherMetrics, err := newDispatcherMetrics(provider, logger) + if err != nil { + logger.Errorf("failed to create dispatcher metrics: %v", err) + return nil + } + d := &DefaultServerDispatcher{ + logger: logger, queueMap: queueMap, - requestChannel: nil, + requestChannel: make(chan string, 20), readyForDispatch: make(chan string, 1), + timerC: make(chan string, 10), + stoppedC: make(chan struct{}, 1), timeout: defaultMessageTimeout, + metrics: dispatcherMetrics, } d.pendingRequestState = NewServerState(&d.mutex) + + dispatcherMetrics.ObserveQueues(queueMap) + dispatcherMetrics.ObserveInFlightRequests(d.pendingRequestState.(*serverState)) + return d } func (d *DefaultServerDispatcher) Start() { - d.mutex.Lock() - defer d.mutex.Unlock() - d.requestChannel = make(chan string, 20) + d.running.Store(true) + + d.queueMap.Init() + d.requestChannel = make(chan string, 30) + d.readyForDispatch = make(chan string, 1) d.timerC = make(chan string, 10) d.stoppedC = make(chan struct{}, 1) - d.running = true + go d.messagePump() } func (d *DefaultServerDispatcher) IsRunning() bool { - d.mutex.RLock() - defer d.mutex.RUnlock() - return d.running + return d.running.Load() } func (d *DefaultServerDispatcher) Stop() { - d.mutex.Lock() - defer d.mutex.Unlock() - d.running = false + d.running.Store(false) + + // Close all channels close(d.stoppedC) + close(d.readyForDispatch) + close(d.timerC) + close(d.requestChannel) } func (d *DefaultServerDispatcher) SetTimeout(timeout time.Duration) { @@ -436,9 +467,7 @@ func (d *DefaultServerDispatcher) CreateClient(clientID string) { func (d *DefaultServerDispatcher) DeleteClient(clientID string) { d.queueMap.Remove(clientID) if d.IsRunning() { - d.mutex.RLock() d.requestChannel <- clientID - d.mutex.RUnlock() } } @@ -465,9 +494,9 @@ func (d *DefaultServerDispatcher) SendRequest(clientID string, req RequestBundle if err := q.Push(req); err != nil { return err } - d.mutex.RLock() + d.requestChannel <- clientID - d.mutex.RUnlock() + return nil } @@ -481,21 +510,19 @@ func (d *DefaultServerDispatcher) messagePump() { var clientQueue RequestQueue clientContextMap := map[string]clientTimeoutContext{} // Empty at the beginning - reqChan := func() chan string { - d.mutex.RLock() - defer d.mutex.RUnlock() - return d.requestChannel - } - // Dispatcher Loop for { select { case <-d.stoppedC: // server was stopped d.queueMap.Init() - log.Info("stopped processing requests") + d.logger.Info("stopped processing requests") return - case clientID = <-reqChan(): + case clientID, ok = <-d.requestChannel: + // Request channel closed, stopping dispatcher + if !ok { + continue + } // Check whether there is a request queue for the specified client clientQueue, ok = d.queueMap.Get(clientID) if !ok { @@ -508,44 +535,42 @@ func (d *DefaultServerDispatcher) messagePump() { } continue } + // Check whether we can transmit to client clientCtx, ok = clientContextMap[clientID] - if !ok { - // First request for this client, ready to transmit - rdy = true - } else { - // If there is no active context, the client is ready to transmit - rdy = !clientCtx.isActive() - } + // Ready to transmit if its the first request or previous request timed out + rdy = !ok || !clientCtx.isActive() + case clientID, ok = <-d.timerC: // Timeout elapsed if !ok { continue } // Canceling timeout context - log.Debugf("timeout for client %v, canceling message", clientID) + d.logger.Debugf("timeout for client %v, canceling message", clientID) clientCtx = clientContextMap[clientID] if clientCtx.isActive() { clientCtx.cancel() clientContextMap[clientID] = clientTimeoutContext{} } + if d.pendingRequestState.HasPendingRequest(clientID) { // Current request for client timed out. Removing request and triggering cancel callback q, found := d.queueMap.Get(clientID) if !found { // Possible race condition: queue was already removed - log.Errorf("dispatcher timeout for client %s triggered, but no request queue found", clientID) + d.logger.Errorf("dispatcher timeout for client %s triggered, but no request queue found", clientID) continue } el := q.Peek() if el == nil { // Should never happen - log.Error("dispatcher timeout for client %s triggered, but no pending request found", clientID) + d.logger.Error("dispatcher timeout for client %s triggered, but no pending request found", clientID) continue } bundle, _ := el.(RequestBundle) d.CompleteRequest(clientID, bundle.Call.UniqueId) - log.Infof("request %v for %v timed out", bundle.Call.UniqueId, clientID) + d.logger.Infof("request %v for %v timed out", bundle.Call.UniqueId, clientID) if d.onRequestCancel != nil { d.onRequestCancel(clientID, bundle.Call.UniqueId, bundle.Call.Payload, ocpp.NewError(GenericError, "Request timed out", bundle.Call.UniqueId)) @@ -564,7 +589,7 @@ func (d *DefaultServerDispatcher) messagePump() { // Ready to transmit rdy = true } - log.Debugf("%v ready to transmit again", clientID) + d.logger.Debugf("%v ready to transmit again", clientID) } // Only dispatch request if able to send and request queue isn't empty @@ -585,7 +610,7 @@ func (d *DefaultServerDispatcher) dispatchNextRequest(clientID string) (clientCt // Get first element in queue q, ok := d.queueMap.Get(clientID) if !ok { - log.Errorf("failed to dispatch next request for %s, no request queue available", clientID) + d.logger.Errorf("failed to dispatch next request for %s, no request queue available", clientID) return } el := q.Peek() @@ -595,7 +620,7 @@ func (d *DefaultServerDispatcher) dispatchNextRequest(clientID string) (clientCt d.pendingRequestState.AddPendingRequest(clientID, callID, bundle.Call.Payload) err := d.network.Write(clientID, jsonMessage) if err != nil { - log.Errorf("error while sending message: %v", err) + d.logger.Errorf("error while sending message: %v", err) // TODO: handle retransmission instead of removing pending request d.CompleteRequest(clientID, callID) if d.onRequestCancel != nil { @@ -606,29 +631,32 @@ func (d *DefaultServerDispatcher) dispatchNextRequest(clientID string) (clientCt } // Create and return context (only if timeout is set) if d.timeout > 0 { - ctx, cancel := context.WithTimeout(context.TODO(), d.timeout) + ctx, cancel := context.WithTimeout(context.Background(), d.timeout) clientCtx = clientTimeoutContext{ctx: ctx, cancel: cancel} } - log.Infof("dispatched request %s for %s", callID, clientID) - log.Debugf("sent JSON message to %s: %s", clientID, string(jsonMessage)) + d.logger.Infof("dispatched request %s for %s", callID, clientID) + d.logger.Debugf("sent JSON message to %s: %s", clientID, string(jsonMessage)) return } func (d *DefaultServerDispatcher) waitForTimeout(clientID string, clientCtx clientTimeoutContext) { defer clientCtx.cancel() - log.Debugf("started timeout timer for %s", clientID) + d.logger.Debugf("started timeout timer for %s", clientID) select { case <-clientCtx.ctx.Done(): err := clientCtx.ctx.Err() - if err == context.DeadlineExceeded { + switch { + case errors.Is(err, context.DeadlineExceeded): // Timeout triggered, notifying messagePump d.mutex.RLock() - defer d.mutex.RUnlock() - if d.running { - d.timerC <- clientID + running := d.running.Load() + timerC := d.timerC + d.mutex.RUnlock() + if running && timerC != nil { + timerC <- clientID } - } else { - log.Debugf("timeout canceled for %s", clientID) + default: + d.logger.Debugf("timeout canceled for %s", clientID) } case <-d.stoppedC: // server was stopped, every pending timeout gets canceled @@ -638,23 +666,23 @@ func (d *DefaultServerDispatcher) waitForTimeout(clientID string, clientCtx clie func (d *DefaultServerDispatcher) CompleteRequest(clientID string, requestID string) { q, ok := d.queueMap.Get(clientID) if !ok { - log.Errorf("attempting to complete request for client %v, but no matching queue found", clientID) + d.logger.Errorf("attempting to complete request for client %v, but no matching queue found", clientID) return } el := q.Peek() if el == nil { - log.Errorf("attempting to pop front of queue, but queue is empty") + d.logger.Errorf("attempting to pop front of queue, but queue is empty") return } bundle, _ := el.(RequestBundle) callID := bundle.Call.GetUniqueId() if callID != requestID { - log.Errorf("internal state mismatch: processing response for %v but expected response for %v", requestID, callID) + d.logger.Errorf("internal state mismatch: processing response for %v but expected response for %v", requestID, callID) return } q.Pop() d.pendingRequestState.DeletePendingRequest(clientID, requestID) - log.Debugf("completed request %s for %s", callID, clientID) + d.logger.Debugf("completed request %s for %s", callID, clientID) // Signal that next message in queue may be sent d.readyForDispatch <- clientID } diff --git a/ocppj/dispatcher_metrics.go b/ocppj/dispatcher_metrics.go new file mode 100644 index 00000000..1b195719 --- /dev/null +++ b/ocppj/dispatcher_metrics.go @@ -0,0 +1,106 @@ +package ocppj + +import ( + "context" + + "github.com/pkg/errors" + "github.com/xBlaz3kx/ocpp-go/logging" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" +) + +const ( + dispatcherQueueSize = "dispatcher_queue_size" + dispatcherPendingRequest = "dispatcher_pending_requests" +) + +type dispatcherMetrics struct { + logger logging.Logger + meter metric.Meter + + requestQueue metric.Int64ObservableGauge + pendingRequests metric.Int64ObservableUpDownCounter +} + +func newDispatcherMetrics(meterProvider metric.MeterProvider, logger logging.Logger) (*dispatcherMetrics, error) { + if meterProvider == nil { + return nil, errors.New("meterProvider is nil") + } + + meter := meterProvider.Meter("server_dispatcher") + + clientQueue, err := meter.Int64ObservableGauge( + dispatcherQueueSize, + metric.WithDescription("Number of messages in the dispatcher's queue"), + ) + if err != nil { + return nil, err + } + + clientPendingRequest, err := meter.Int64ObservableUpDownCounter( + dispatcherPendingRequest, + metric.WithDescription("Number of pending requests in the dispatcher"), + ) + if err != nil { + return nil, err + } + + dispatcher := &dispatcherMetrics{ + meter: meter, + requestQueue: clientQueue, + pendingRequests: clientPendingRequest, + logger: logger, + } + + return dispatcher, nil +} + +func (d *dispatcherMetrics) ObserveInFlightRequests(state *serverState) { + if d.meter == nil { + return + } + + _, err := d.meter.RegisterCallback(func(ctx context.Context, obs metric.Observer) error { + state.mutex.RLock() + currentState := state.pendingRequestState + state.mutex.RUnlock() + + for clientID, clientState := range currentState { + inFlightRequest := int64(0) + if clientState.HasPendingRequest() { + inFlightRequest = 1 + } + obs.ObserveInt64( + d.pendingRequests, + inFlightRequest, + metric.WithAttributes(attribute.String("client_id", clientID)), + ) + } + return nil + }, d.pendingRequests) + if err != nil { + d.logger.Errorf("failed to register callback for inflight queue size: %v", err) + } +} + +func (d *dispatcherMetrics) ObserveQueues(queue ServerQueueMap) { + if d.meter == nil { + return + } + + _, err := d.meter.RegisterCallback( + func(ctx context.Context, obs metric.Observer) error { + for clientID, queueSize := range queue.SizePerClient() { + obs.ObserveInt64( + d.requestQueue, + int64(queueSize), + metric.WithAttributes(attribute.String("client_id", clientID)), + ) + } + return nil + }, + d.requestQueue) + if err != nil { + d.logger.Errorf("failed to register callback for dispatcher queue size: %v", err) + } +} diff --git a/ocppj/dispatcher_test.go b/ocppj/dispatcher_test.go index a33d5162..2ad4d055 100644 --- a/ocppj/dispatcher_test.go +++ b/ocppj/dispatcher_test.go @@ -1,17 +1,16 @@ package ocppj_test import ( - "fmt" + "errors" "sync" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "go.opentelemetry.io/otel/metric/noop" - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocppj" ) type ServerDispatcherTestSuite struct { @@ -29,7 +28,7 @@ func (s *ServerDispatcherTestSuite) SetupTest() { mockProfile := ocpp.NewProfile("mock", &MockFeature{}) s.endpoint.AddProfile(mockProfile) s.queueMap = ocppj.NewFIFOQueueMap(10) - s.dispatcher = ocppj.NewDefaultServerDispatcher(s.queueMap) + s.dispatcher = ocppj.NewDefaultServerDispatcher(s.queueMap, noop.NewMeterProvider(), nil) s.state = ocppj.NewServerState(&s.mutex) s.dispatcher.SetPendingRequestState(s.state) s.websocketServer = MockWebsocketServer{} @@ -37,53 +36,51 @@ func (s *ServerDispatcherTestSuite) SetupTest() { } func (s *ServerDispatcherTestSuite) TestServerSendRequest() { - t := s.T() // Setup clientID := "client1" sent := make(chan bool, 1) s.websocketServer.On("Write", mock.AnythingOfType("string"), mock.Anything).Run(func(args mock.Arguments) { id, _ := args.Get(0).(string) - assert.Equal(t, clientID, id) + s.Assert().Equal(clientID, id) sent <- true }).Return(nil) timeout := time.Second * 1 s.dispatcher.SetTimeout(timeout) s.dispatcher.SetOnRequestCanceled(func(cID string, rID string, request ocpp.Request, err *ocpp.Error) { - require.Fail(t, "unexpected OnRequestCanceled") + s.Require().Fail("unexpected OnRequestCanceled") }) s.dispatcher.Start() - require.True(t, s.dispatcher.IsRunning()) + s.Require().True(s.dispatcher.IsRunning()) // Simulate client connection s.dispatcher.CreateClient(clientID) // Create and send mock request req := newMockRequest("somevalue") call, err := s.endpoint.CreateCall(req) - require.NoError(t, err) + s.Require().NoError(err) requestID := call.UniqueId data, err := call.MarshalJSON() - require.NoError(t, err) + s.Require().NoError(err) bundle := ocppj.RequestBundle{Call: call, Data: data} err = s.dispatcher.SendRequest(clientID, bundle) - require.NoError(t, err) + s.Require().NoError(err) // Check underlying queue q, ok := s.queueMap.Get(clientID) - require.True(t, ok) - assert.False(t, q.IsEmpty()) - assert.Equal(t, 1, q.Size()) + s.Require().True(ok) + s.Assert().False(q.IsEmpty()) + s.Assert().Equal(1, q.Size()) // Wait for websocket to send message _, ok = <-sent - assert.True(t, ok) - assert.True(t, s.state.HasPendingRequest(clientID)) + s.Assert().True(ok) + s.Assert().True(s.state.HasPendingRequest(clientID)) // Complete request s.dispatcher.CompleteRequest(clientID, requestID) - assert.False(t, s.state.HasPendingRequest(clientID)) - assert.True(t, q.IsEmpty()) + s.Assert().False(s.state.HasPendingRequest(clientID)) + s.Assert().True(q.IsEmpty()) // Assert that no timeout is invoked time.Sleep(1300 * time.Millisecond) } func (s *ServerDispatcherTestSuite) TestServerRequestCanceled() { - t := s.T() // Setup clientID := "client1" canceled := make(chan bool, 1) @@ -93,142 +90,139 @@ func (s *ServerDispatcherTestSuite) TestServerRequestCanceled() { // This never starts a timeout s.websocketServer.On("Write", mock.AnythingOfType("string"), mock.Anything).Run(func(args mock.Arguments) { id, _ := args.Get(0).(string) - assert.Equal(t, clientID, id) + s.Assert().Equal(clientID, id) <-writeC - }).Return(fmt.Errorf(errMsg)) + }).Return(errors.New(errMsg)) // Create mock request req := newMockRequest("somevalue") call, err := s.endpoint.CreateCall(req) - require.NoError(t, err) + s.Require().NoError(err) requestID := call.UniqueId data, err := call.MarshalJSON() - require.NoError(t, err) + s.Require().NoError(err) bundle := ocppj.RequestBundle{Call: call, Data: data} // Set canceled callback s.dispatcher.SetOnRequestCanceled(func(cID string, rID string, request ocpp.Request, err *ocpp.Error) { - assert.Equal(t, clientID, cID) - assert.Equal(t, requestID, rID) - assert.Equal(t, MockFeatureName, request.GetFeatureName()) - assert.Equal(t, req, request) - assert.Equal(t, ocppj.InternalError, err.Code) - assert.Equal(t, errMsg, err.Description) + s.Assert().Equal(clientID, cID) + s.Assert().Equal(requestID, rID) + s.Assert().Equal(MockFeatureName, request.GetFeatureName()) + s.Assert().Equal(req, request) + s.Assert().Equal(ocppj.InternalError, err.Code) + s.Assert().Equal(errMsg, err.Description) canceled <- true }) s.dispatcher.Start() - require.True(t, s.dispatcher.IsRunning()) + s.Require().True(s.dispatcher.IsRunning()) // Simulate client connection s.dispatcher.CreateClient(clientID) // Send mock request err = s.dispatcher.SendRequest(clientID, bundle) - require.NoError(t, err) + s.Require().NoError(err) // Check underlying queue time.Sleep(100 * time.Millisecond) q, ok := s.queueMap.Get(clientID) - require.True(t, ok) - assert.False(t, q.IsEmpty()) - assert.Equal(t, 1, q.Size()) - assert.True(t, s.state.HasPendingRequest(clientID)) + s.Require().True(ok) + s.Assert().False(q.IsEmpty()) + s.Assert().Equal(1, q.Size()) + s.Assert().True(s.state.HasPendingRequest(clientID)) // Signal that write can occur now, then check canceled request writeC <- true _, ok = <-canceled - require.True(t, ok) - assert.False(t, s.state.HasPendingRequest(clientID)) - assert.True(t, q.IsEmpty()) + s.Require().True(ok) + s.Assert().False(s.state.HasPendingRequest(clientID)) + s.Assert().True(q.IsEmpty()) } func (s *ServerDispatcherTestSuite) TestCreateClient() { - t := s.T() // Setup clientID := "client1" s.dispatcher.Start() - require.True(t, s.dispatcher.IsRunning()) + s.Require().True(s.dispatcher.IsRunning()) // No client state created yet _, ok := s.queueMap.Get(clientID) - assert.False(t, ok) + s.Assert().False(ok) // Create client state s.dispatcher.CreateClient(clientID) _, ok = s.queueMap.Get(clientID) - assert.True(t, ok) - assert.False(t, s.state.HasPendingRequest(clientID)) + s.Assert().True(ok) + s.Assert().False(s.state.HasPendingRequest(clientID)) } func (s *ServerDispatcherTestSuite) TestDeleteClient() { - t := s.T() // Setup clientID := "client1" sent := make(chan bool, 1) s.websocketServer.On("Write", mock.AnythingOfType("string"), mock.Anything).Run(func(args mock.Arguments) { id, _ := args.Get(0).(string) - assert.Equal(t, clientID, id) + s.Assert().Equal(clientID, id) sent <- true }).Return(nil) s.dispatcher.Start() - require.True(t, s.dispatcher.IsRunning()) + s.Require().True(s.dispatcher.IsRunning()) // Simulate client connection s.dispatcher.CreateClient(clientID) // Create and send mock request req := newMockRequest("somevalue") call, err := s.endpoint.CreateCall(req) - require.NoError(t, err) + s.Require().NoError(err) data, err := call.MarshalJSON() - require.NoError(t, err) + s.Require().NoError(err) bundle := ocppj.RequestBundle{Call: call, Data: data} err = s.dispatcher.SendRequest(clientID, bundle) - require.NoError(t, err) + s.Require().NoError(err) // Wait for websocket to send message _, ok := <-sent - assert.True(t, ok) + s.Assert().True(ok) // Delete client s.dispatcher.DeleteClient(clientID) // Pending request is still expected to be there - assert.True(t, s.state.HasPendingRequest(clientID)) + s.Assert().True(s.state.HasPendingRequest(clientID)) } func (s *ServerDispatcherTestSuite) TestServerDispatcherTimeout() { - t := s.T() // Setup clientID := "client1" canceled := make(chan bool, 1) s.websocketServer.On("Write", mock.AnythingOfType("string"), mock.Anything).Run(func(args mock.Arguments) { id, _ := args.Get(0).(string) - assert.Equal(t, clientID, id) + s.Assert().Equal(clientID, id) }).Return(nil) // Create mock request req := newMockRequest("somevalue") call, err := s.endpoint.CreateCall(req) - require.NoError(t, err) + s.Require().NoError(err) requestID := call.UniqueId data, err := call.MarshalJSON() - require.NoError(t, err) + s.Require().NoError(err) bundle := ocppj.RequestBundle{Call: call, Data: data} // Set canceled callback s.dispatcher.SetOnRequestCanceled(func(cID string, rID string, request ocpp.Request, err *ocpp.Error) { - assert.Equal(t, clientID, cID) - assert.Equal(t, requestID, rID) - assert.Equal(t, MockFeatureName, request.GetFeatureName()) - assert.Equal(t, req, request) - assert.Equal(t, ocppj.GenericError, err.Code) - assert.Equal(t, "Request timed out", err.Description) + s.Assert().Equal(clientID, cID) + s.Assert().Equal(requestID, rID) + s.Assert().Equal(MockFeatureName, request.GetFeatureName()) + s.Assert().Equal(req, request) + s.Assert().Equal(ocppj.GenericError, err.Code) + s.Assert().Equal("Request timed out", err.Description) canceled <- true }) // Set timeout and start timeout := time.Second * 1 s.dispatcher.SetTimeout(timeout) s.dispatcher.Start() - require.True(t, s.dispatcher.IsRunning()) + s.Require().True(s.dispatcher.IsRunning()) // Simulate client connection s.dispatcher.CreateClient(clientID) // Send mock request startTime := time.Now() err = s.dispatcher.SendRequest(clientID, bundle) - require.NoError(t, err) + s.Require().NoError(err) // Wait for timeout, canceled callback will be invoked _, ok := <-canceled - assert.True(t, ok) + s.Assert().True(ok) elapsed := time.Since(startTime) - assert.GreaterOrEqual(t, elapsed.Seconds(), timeout.Seconds()) + s.Assert().GreaterOrEqual(elapsed.Seconds(), timeout.Seconds()) clientQ, _ := s.queueMap.Get(clientID) - assert.True(t, clientQ.IsEmpty()) + s.Assert().True(clientQ.IsEmpty()) } type ClientDispatcherTestSuite struct { @@ -245,7 +239,7 @@ func (c *ClientDispatcherTestSuite) SetupTest() { mockProfile := ocpp.NewProfile("mock", &MockFeature{}) c.endpoint.AddProfile(mockProfile) c.queue = ocppj.NewFIFOClientQueue(10) - c.dispatcher = ocppj.NewDefaultClientDispatcher(c.queue) + c.dispatcher = ocppj.NewDefaultClientDispatcher(c.queue, nil) c.state = ocppj.NewClientState() c.dispatcher.SetPendingRequestState(c.state) c.websocketClient = MockWebsocketClient{} @@ -253,84 +247,81 @@ func (c *ClientDispatcherTestSuite) SetupTest() { } func (c *ClientDispatcherTestSuite) TestClientSendRequest() { - t := c.T() // Setup sent := make(chan bool, 1) c.websocketClient.On("Write", mock.Anything).Run(func(args mock.Arguments) { sent <- true }).Return(nil) c.dispatcher.Start() - require.True(t, c.dispatcher.IsRunning()) + c.Require().True(c.dispatcher.IsRunning()) // Create and send mock request req := newMockRequest("somevalue") call, err := c.endpoint.CreateCall(req) - require.NoError(t, err) + c.Require().NoError(err) requestID := call.UniqueId data, err := call.MarshalJSON() - require.NoError(t, err) + c.Require().NoError(err) bundle := ocppj.RequestBundle{Call: call, Data: data} err = c.dispatcher.SendRequest(bundle) - require.NoError(t, err) + c.Require().NoError(err) // Check underlying queue - assert.False(t, c.queue.IsEmpty()) - assert.Equal(t, 1, c.queue.Size()) + c.Assert().False(c.queue.IsEmpty()) + c.Assert().Equal(1, c.queue.Size()) // Wait for websocket to send message _, ok := <-sent - assert.True(t, ok) - assert.True(t, c.state.HasPendingRequest()) + c.Assert().True(ok) + c.Assert().True(c.state.HasPendingRequest()) // Complete request c.dispatcher.CompleteRequest(requestID) - assert.False(t, c.state.HasPendingRequest()) - assert.True(t, c.queue.IsEmpty()) + c.Assert().False(c.state.HasPendingRequest()) + c.Assert().True(c.queue.IsEmpty()) } func (c *ClientDispatcherTestSuite) TestClientRequestCanceled() { - t := c.T() // Setup canceled := make(chan bool, 1) writeC := make(chan bool, 1) errMsg := "mockError" c.websocketClient.On("Write", mock.Anything).Run(func(args mock.Arguments) { <-writeC - }).Return(fmt.Errorf(errMsg)) + }).Return(errors.New(errMsg)) // Create mock request req := newMockRequest("somevalue") call, err := c.endpoint.CreateCall(req) - require.NoError(t, err) + c.Require().NoError(err) requestID := call.UniqueId data, err := call.MarshalJSON() - require.NoError(t, err) + c.Require().NoError(err) bundle := ocppj.RequestBundle{Call: call, Data: data} // Set canceled callback c.dispatcher.SetOnRequestCanceled(func(rID string, request ocpp.Request, err *ocpp.Error) { - assert.Equal(t, requestID, rID) - assert.Equal(t, MockFeatureName, request.GetFeatureName()) - assert.Equal(t, req, request) - assert.Equal(t, ocppj.InternalError, err.Code) - assert.Equal(t, errMsg, err.Description) + c.Assert().Equal(requestID, rID) + c.Assert().Equal(MockFeatureName, request.GetFeatureName()) + c.Assert().Equal(req, request) + c.Assert().Equal(ocppj.InternalError, err.Code) + c.Assert().Equal(errMsg, err.Description) canceled <- true }) c.dispatcher.Start() - require.True(t, c.dispatcher.IsRunning()) + c.Require().True(c.dispatcher.IsRunning()) // Send mock request err = c.dispatcher.SendRequest(bundle) - require.NoError(t, err) + c.Require().NoError(err) // Check underlying queue time.Sleep(100 * time.Millisecond) - assert.False(t, c.queue.IsEmpty()) - assert.Equal(t, 1, c.queue.Size()) - assert.True(t, c.state.HasPendingRequest()) + c.Assert().False(c.queue.IsEmpty()) + c.Assert().Equal(1, c.queue.Size()) + c.Assert().True(c.state.HasPendingRequest()) // Signal that write can occur now, then check canceled request writeC <- true _, ok := <-canceled - require.True(t, ok) - assert.False(t, c.state.HasPendingRequest()) - assert.True(t, c.queue.IsEmpty()) + c.Require().True(ok) + c.Assert().False(c.state.HasPendingRequest()) + c.Assert().True(c.queue.IsEmpty()) } func (c *ClientDispatcherTestSuite) TestClientDispatcherTimeout() { - t := c.T() // Setup writeC := make(chan bool, 1) timeout := make(chan bool, 1) @@ -340,120 +331,118 @@ func (c *ClientDispatcherTestSuite) TestClientDispatcherTimeout() { // Create mock request req := newMockRequest("somevalue") call, err := c.endpoint.CreateCall(req) - require.NoError(t, err) + c.Require().NoError(err) requestID := call.UniqueId data, err := call.MarshalJSON() - require.NoError(t, err) + c.Require().NoError(err) bundle := ocppj.RequestBundle{Call: call, Data: data} // Set low timeout to trigger OnRequestCanceled callback c.dispatcher.SetTimeout(1 * time.Second) c.dispatcher.SetOnRequestCanceled(func(rID string, request ocpp.Request, err *ocpp.Error) { - assert.Equal(t, requestID, rID) - assert.Equal(t, MockFeatureName, request.GetFeatureName()) - assert.Equal(t, req, request) - assert.Equal(t, ocppj.GenericError, err.Code) - assert.Equal(t, "Request timed out", err.Description) + c.Assert().Equal(requestID, rID) + c.Assert().Equal(MockFeatureName, request.GetFeatureName()) + c.Assert().Equal(req, request) + c.Assert().Equal(ocppj.GenericError, err.Code) + c.Assert().Equal("Request timed out", err.Description) timeout <- true }) c.dispatcher.Start() - require.True(t, c.dispatcher.IsRunning()) + c.Require().True(c.dispatcher.IsRunning()) // Send mocked request err = c.dispatcher.SendRequest(bundle) - require.NoError(t, err) + c.Require().NoError(err) // Check status after sending request <-writeC - assert.True(t, c.state.HasPendingRequest()) + c.Assert().True(c.state.HasPendingRequest()) // Wait for timeout _, ok := <-timeout - assert.True(t, ok) - assert.False(t, c.state.HasPendingRequest()) - assert.True(t, c.queue.IsEmpty()) + c.Assert().True(ok) + c.Assert().False(c.state.HasPendingRequest()) + c.Assert().True(c.queue.IsEmpty()) } func (c *ClientDispatcherTestSuite) TestClientPauseDispatcher() { - t := c.T() // Create mock request timeout := make(chan bool, 1) c.websocketClient.On("Write", mock.Anything).Return(nil) req := newMockRequest("somevalue") call, err := c.endpoint.CreateCall(req) - require.NoError(t, err) + c.Require().NoError(err) requestID := call.UniqueId data, err := call.MarshalJSON() - require.NoError(t, err) + c.Require().NoError(err) bundle := ocppj.RequestBundle{Call: call, Data: data} // Set timeout to test pause functionality c.dispatcher.SetTimeout(500 * time.Millisecond) // The callback will only be triggered at the end of the test case c.dispatcher.SetOnRequestCanceled(func(rID string, request ocpp.Request, err *ocpp.Error) { - assert.Equal(t, requestID, rID) - assert.Equal(t, MockFeatureName, request.GetFeatureName()) - assert.Equal(t, req, request) + c.Assert().Equal(requestID, rID) + c.Assert().Equal(MockFeatureName, request.GetFeatureName()) + c.Assert().Equal(req, request) timeout <- true }) c.dispatcher.Start() - require.True(t, c.dispatcher.IsRunning()) + c.Require().True(c.dispatcher.IsRunning()) err = c.dispatcher.SendRequest(bundle) - require.NoError(t, err) + c.Require().NoError(err) // Pause and attempt retransmission 2 times for i := 0; i < 2; i++ { time.Sleep(200 * time.Millisecond) // Pause dispatcher c.dispatcher.Pause() - assert.True(t, c.dispatcher.IsPaused()) + c.Assert().True(c.dispatcher.IsPaused()) // Elapsed time since start ~ 1 second, no timeout should be triggered (set to 0.5 seconds) time.Sleep(800 * time.Millisecond) - assert.True(t, c.state.HasPendingRequest()) - assert.False(t, c.queue.IsEmpty()) + c.Assert().True(c.state.HasPendingRequest()) + c.Assert().False(c.queue.IsEmpty()) // Resume and restart transmission timer c.dispatcher.Resume() - assert.False(t, c.dispatcher.IsPaused()) + c.Assert().False(c.dispatcher.IsPaused()) } // Wait for timeout _, ok := <-timeout - assert.True(t, ok) - assert.False(t, c.state.HasPendingRequest()) - assert.True(t, c.queue.IsEmpty()) + c.Assert().True(ok) + c.Assert().False(c.state.HasPendingRequest()) + c.Assert().True(c.queue.IsEmpty()) } func (c *ClientDispatcherTestSuite) TestClientSendPausedDispatcher() { - t := c.T() // Create mock request c.websocketClient.On("Write", mock.Anything).Run(func(args mock.Arguments) { - require.Fail(t, "write should never be called") + c.Require().Fail("write should never be called") }).Return(nil) // Set timeout (unused for this test) c.dispatcher.SetTimeout(1 * time.Second) // The callback will only be triggered at the end of the test case c.dispatcher.SetOnRequestCanceled(func(rID string, request ocpp.Request, err *ocpp.Error) { - require.Fail(t, "unexpected OnRequestCanceled") + c.Require().Fail("unexpected OnRequestCanceled") }) c.dispatcher.Start() - require.True(t, c.dispatcher.IsRunning()) + c.Require().True(c.dispatcher.IsRunning()) // Pause, then send request c.dispatcher.Pause() - assert.False(t, c.state.HasPendingRequest()) - assert.True(t, c.queue.IsEmpty()) + c.Assert().False(c.state.HasPendingRequest()) + c.Assert().True(c.queue.IsEmpty()) requestIDs := []string{} requestNumber := 2 for i := 0; i < requestNumber; i++ { req := newMockRequest("somevalue") call, err := c.endpoint.CreateCall(req) - require.NoError(t, err) + c.Require().NoError(err) requestID := call.UniqueId data, err := call.MarshalJSON() - require.NoError(t, err) + c.Require().NoError(err) bundle := ocppj.RequestBundle{Call: call, Data: data} err = c.dispatcher.SendRequest(bundle) - require.NoError(t, err) + c.Require().NoError(err) requestIDs = append(requestIDs, requestID) } time.Sleep(500 * time.Millisecond) // Request is queued - assert.Equal(t, requestNumber, c.queue.Size()) - assert.False(t, c.state.HasPendingRequest()) + c.Assert().Equal(requestNumber, c.queue.Size()) + c.Assert().False(c.state.HasPendingRequest()) // After waiting for some time, no timeout was triggered and no pending requests time.Sleep(1 * time.Second) - assert.Equal(t, requestNumber, c.queue.Size()) - assert.False(t, c.state.HasPendingRequest()) + c.Assert().Equal(requestNumber, c.queue.Size()) + c.Assert().False(c.state.HasPendingRequest()) } diff --git a/ocppj/mocks/mock_CanceledRequestHandler.go b/ocppj/mocks/mock_CanceledRequestHandler.go index be1be073..0d2ebbf4 100644 --- a/ocppj/mocks/mock_CanceledRequestHandler.go +++ b/ocppj/mocks/mock_CanceledRequestHandler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ocpp "github.com/lorenzodonini/ocpp-go/ocpp" mock "github.com/stretchr/testify/mock" + ocpp "github.com/xBlaz3kx/ocpp-go/ocpp" ) // MockCanceledRequestHandler is an autogenerated mock type for the CanceledRequestHandler type diff --git a/ocppj/mocks/mock_ClientDispatcher.go b/ocppj/mocks/mock_ClientDispatcher.go index 0dd86eff..c23f6f1b 100644 --- a/ocppj/mocks/mock_ClientDispatcher.go +++ b/ocppj/mocks/mock_ClientDispatcher.go @@ -1,16 +1,16 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ocpp "github.com/lorenzodonini/ocpp-go/ocpp" mock "github.com/stretchr/testify/mock" + ocpp "github.com/xBlaz3kx/ocpp-go/ocpp" - ocppj "github.com/lorenzodonini/ocpp-go/ocppj" + ocppj "github.com/xBlaz3kx/ocpp-go/ocppj" time "time" - ws "github.com/lorenzodonini/ocpp-go/ws" + ws "github.com/xBlaz3kx/ocpp-go/ws" ) // MockClientDispatcher is an autogenerated mock type for the ClientDispatcher type diff --git a/ocppj/mocks/mock_ClientHandler.go b/ocppj/mocks/mock_ClientHandler.go index f08a868f..7c0f2cd6 100644 --- a/ocppj/mocks/mock_ClientHandler.go +++ b/ocppj/mocks/mock_ClientHandler.go @@ -1,11 +1,11 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( mock "github.com/stretchr/testify/mock" - ws "github.com/lorenzodonini/ocpp-go/ws" + ws "github.com/xBlaz3kx/ocpp-go/ws" ) // MockClientHandler is an autogenerated mock type for the ClientHandler type diff --git a/ocppj/mocks/mock_ClientState.go b/ocppj/mocks/mock_ClientState.go index d07d228c..f154066a 100644 --- a/ocppj/mocks/mock_ClientState.go +++ b/ocppj/mocks/mock_ClientState.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ocpp "github.com/lorenzodonini/ocpp-go/ocpp" mock "github.com/stretchr/testify/mock" + ocpp "github.com/xBlaz3kx/ocpp-go/ocpp" ) // MockClientState is an autogenerated mock type for the ClientState type diff --git a/ocppj/mocks/mock_ErrorHandler.go b/ocppj/mocks/mock_ErrorHandler.go index 3d956910..d1507a9b 100644 --- a/ocppj/mocks/mock_ErrorHandler.go +++ b/ocppj/mocks/mock_ErrorHandler.go @@ -1,12 +1,12 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ocpp "github.com/lorenzodonini/ocpp-go/ocpp" mock "github.com/stretchr/testify/mock" + ocpp "github.com/xBlaz3kx/ocpp-go/ocpp" - ws "github.com/lorenzodonini/ocpp-go/ws" + ws "github.com/xBlaz3kx/ocpp-go/ws" ) // MockErrorHandler is an autogenerated mock type for the ErrorHandler type diff --git a/ocppj/mocks/mock_InvalidMessageHook.go b/ocppj/mocks/mock_InvalidMessageHook.go index 1e82f54e..aa8c0954 100644 --- a/ocppj/mocks/mock_InvalidMessageHook.go +++ b/ocppj/mocks/mock_InvalidMessageHook.go @@ -1,12 +1,12 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ocpp "github.com/lorenzodonini/ocpp-go/ocpp" mock "github.com/stretchr/testify/mock" + ocpp "github.com/xBlaz3kx/ocpp-go/ocpp" - ws "github.com/lorenzodonini/ocpp-go/ws" + ws "github.com/xBlaz3kx/ocpp-go/ws" ) // MockInvalidMessageHook is an autogenerated mock type for the InvalidMessageHook type diff --git a/ocppj/mocks/mock_Message.go b/ocppj/mocks/mock_Message.go index d741881a..9d85d33a 100644 --- a/ocppj/mocks/mock_Message.go +++ b/ocppj/mocks/mock_Message.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ocppj "github.com/lorenzodonini/ocpp-go/ocppj" mock "github.com/stretchr/testify/mock" + ocppj "github.com/xBlaz3kx/ocpp-go/ocppj" ) // MockMessage is an autogenerated mock type for the Message type diff --git a/ocppj/mocks/mock_RequestHandler.go b/ocppj/mocks/mock_RequestHandler.go index 5753bfe8..d7f69b14 100644 --- a/ocppj/mocks/mock_RequestHandler.go +++ b/ocppj/mocks/mock_RequestHandler.go @@ -1,12 +1,12 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ocpp "github.com/lorenzodonini/ocpp-go/ocpp" mock "github.com/stretchr/testify/mock" + ocpp "github.com/xBlaz3kx/ocpp-go/ocpp" - ws "github.com/lorenzodonini/ocpp-go/ws" + ws "github.com/xBlaz3kx/ocpp-go/ws" ) // MockRequestHandler is an autogenerated mock type for the RequestHandler type diff --git a/ocppj/mocks/mock_RequestQueue.go b/ocppj/mocks/mock_RequestQueue.go index 298a42de..6342ce78 100644 --- a/ocppj/mocks/mock_RequestQueue.go +++ b/ocppj/mocks/mock_RequestQueue.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks diff --git a/ocppj/mocks/mock_ResponseHandler.go b/ocppj/mocks/mock_ResponseHandler.go index 038f3a96..becd4ed6 100644 --- a/ocppj/mocks/mock_ResponseHandler.go +++ b/ocppj/mocks/mock_ResponseHandler.go @@ -1,12 +1,12 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ocpp "github.com/lorenzodonini/ocpp-go/ocpp" mock "github.com/stretchr/testify/mock" + ocpp "github.com/xBlaz3kx/ocpp-go/ocpp" - ws "github.com/lorenzodonini/ocpp-go/ws" + ws "github.com/xBlaz3kx/ocpp-go/ws" ) // MockResponseHandler is an autogenerated mock type for the ResponseHandler type diff --git a/ocppj/mocks/mock_ServerDispatcher.go b/ocppj/mocks/mock_ServerDispatcher.go index 85d0f206..bba784d8 100644 --- a/ocppj/mocks/mock_ServerDispatcher.go +++ b/ocppj/mocks/mock_ServerDispatcher.go @@ -1,14 +1,14 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ocppj "github.com/lorenzodonini/ocpp-go/ocppj" mock "github.com/stretchr/testify/mock" + ocppj "github.com/xBlaz3kx/ocpp-go/ocppj" time "time" - ws "github.com/lorenzodonini/ocpp-go/ws" + ws "github.com/xBlaz3kx/ocpp-go/ws" ) // MockServerDispatcher is an autogenerated mock type for the ServerDispatcher type diff --git a/ocppj/mocks/mock_ServerQueueMap.go b/ocppj/mocks/mock_ServerQueueMap.go index d44b8cf7..b8b845f8 100644 --- a/ocppj/mocks/mock_ServerQueueMap.go +++ b/ocppj/mocks/mock_ServerQueueMap.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ocppj "github.com/lorenzodonini/ocpp-go/ocppj" mock "github.com/stretchr/testify/mock" + ocppj "github.com/xBlaz3kx/ocpp-go/ocppj" ) // MockServerQueueMap is an autogenerated mock type for the ServerQueueMap type @@ -225,6 +225,98 @@ func (_c *MockServerQueueMap_Remove_Call) RunAndReturn(run func(string)) *MockSe return _c } +// Size provides a mock function with no fields +func (_m *MockServerQueueMap) Size() int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Size") + } + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +// MockServerQueueMap_Size_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Size' +type MockServerQueueMap_Size_Call struct { + *mock.Call +} + +// Size is a helper method to define mock.On call +func (_e *MockServerQueueMap_Expecter) Size() *MockServerQueueMap_Size_Call { + return &MockServerQueueMap_Size_Call{Call: _e.mock.On("Size")} +} + +func (_c *MockServerQueueMap_Size_Call) Run(run func()) *MockServerQueueMap_Size_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockServerQueueMap_Size_Call) Return(_a0 int) *MockServerQueueMap_Size_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockServerQueueMap_Size_Call) RunAndReturn(run func() int) *MockServerQueueMap_Size_Call { + _c.Call.Return(run) + return _c +} + +// SizePerClient provides a mock function with no fields +func (_m *MockServerQueueMap) SizePerClient() map[string]int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for SizePerClient") + } + + var r0 map[string]int + if rf, ok := ret.Get(0).(func() map[string]int); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string]int) + } + } + + return r0 +} + +// MockServerQueueMap_SizePerClient_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SizePerClient' +type MockServerQueueMap_SizePerClient_Call struct { + *mock.Call +} + +// SizePerClient is a helper method to define mock.On call +func (_e *MockServerQueueMap_Expecter) SizePerClient() *MockServerQueueMap_SizePerClient_Call { + return &MockServerQueueMap_SizePerClient_Call{Call: _e.mock.On("SizePerClient")} +} + +func (_c *MockServerQueueMap_SizePerClient_Call) Run(run func()) *MockServerQueueMap_SizePerClient_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockServerQueueMap_SizePerClient_Call) Return(_a0 map[string]int) *MockServerQueueMap_SizePerClient_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockServerQueueMap_SizePerClient_Call) RunAndReturn(run func() map[string]int) *MockServerQueueMap_SizePerClient_Call { + _c.Call.Return(run) + return _c +} + // NewMockServerQueueMap creates a new instance of MockServerQueueMap. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewMockServerQueueMap(t interface { diff --git a/ocppj/mocks/mock_ServerState.go b/ocppj/mocks/mock_ServerState.go index db612eee..944a9626 100644 --- a/ocppj/mocks/mock_ServerState.go +++ b/ocppj/mocks/mock_ServerState.go @@ -1,12 +1,12 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ocpp "github.com/lorenzodonini/ocpp-go/ocpp" mock "github.com/stretchr/testify/mock" + ocpp "github.com/xBlaz3kx/ocpp-go/ocpp" - ocppj "github.com/lorenzodonini/ocpp-go/ocppj" + ocppj "github.com/xBlaz3kx/ocpp-go/ocppj" ) // MockServerState is an autogenerated mock type for the ServerState type diff --git a/ocppj/mocks/mock_dialector.go b/ocppj/mocks/mock_dialector.go index 0d12e982..ffda4d0d 100644 --- a/ocppj/mocks/mock_dialector.go +++ b/ocppj/mocks/mock_dialector.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ocpp "github.com/lorenzodonini/ocpp-go/ocpp" mock "github.com/stretchr/testify/mock" + ocpp "github.com/xBlaz3kx/ocpp-go/ocpp" ) // Mockdialector is an autogenerated mock type for the dialector type diff --git a/ocppj/ocppj.go b/ocppj/ocppj.go index 3591f95e..c4f68da2 100644 --- a/ocppj/ocppj.go +++ b/ocppj/ocppj.go @@ -7,58 +7,23 @@ import ( "fmt" "math/rand" "reflect" - - "github.com/lorenzodonini/ocpp-go/logging" + "sync/atomic" "gopkg.in/go-playground/validator.v9" - "github.com/lorenzodonini/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp" ) -// The validator, used for validating incoming/outgoing OCPP messages. -var Validate = validator.New() - -// The internal validation settings. Enabled by default. -var validationEnabled bool - -// The internal verbose logger -var log logging.Logger - -var EscapeHTML = true +var EscapeHTML atomic.Bool func init() { - _ = Validate.RegisterValidation("errorCode", IsErrorCodeValid) - log = &logging.VoidLogger{} - validationEnabled = true -} - -// Sets a custom Logger implementation, allowing the ocpp-j package to log events. -// By default, a VoidLogger is used, so no logs will be sent to any output. -// -// The function panics, if a nil logger is passed. -func SetLogger(logger logging.Logger) { - if logger == nil { - panic("cannot set a nil logger") - } - log = logger + EscapeHTML.Store(true) } // Allows an instance of ocppj to configure if the message is Marshaled by escaping special caracters like "<", ">", "&" etc // For more info https://pkg.go.dev/encoding/json#HTMLEscape func SetHTMLEscape(flag bool) { - EscapeHTML = flag -} - -// Allows to enable/disable automatic validation for OCPP messages -// (this includes the field constraints defined for every request/response). -// The feature may be useful when working with OCPP implementations that don't fully comply to the specs. -// -// Validation is enabled by default. -// -// ⚠️ Use at your own risk! When disabled, outgoing and incoming OCPP messages will not be validated anymore, -// potentially leading to errors. -func SetMessageValidation(enabled bool) { - validationEnabled = enabled + EscapeHTML.Store(flag) } // MessageType identifies the type of message exchanged between two OCPP endpoints. @@ -321,7 +286,7 @@ func errorFromValidation(d dialector, validationErrors validator.ValidationError func jsonMarshal(t interface{}) ([]byte, error) { buffer := &bytes.Buffer{} encoder := json.NewEncoder(buffer) - encoder.SetEscapeHTML(EscapeHTML) + encoder.SetEscapeHTML(EscapeHTML.Load()) err := encoder.Encode(t) return bytes.TrimRight(buffer.Bytes(), "\n"), err } @@ -458,7 +423,7 @@ func (endpoint *Endpoint) ParseMessage(arr []interface{}, pendingRequestState Cl } else if typeId == CALL_RESULT { request, ok := pendingRequestState.GetPendingRequest(uniqueId) if !ok { - log.Infof("No previous request %v sent. Discarding response message", uniqueId) + // No logger available in Endpoint.ParseMessage - this is expected to be called from Server/Client which have loggers return nil, nil } profile, _ := endpoint.GetProfileForFeature(request.GetFeatureName()) @@ -479,7 +444,7 @@ func (endpoint *Endpoint) ParseMessage(arr []interface{}, pendingRequestState Cl } else if typeId == CALL_ERROR { _, ok := pendingRequestState.GetPendingRequest(uniqueId) if !ok { - log.Infof("No previous request %v sent. Discarding error message", uniqueId) + // No logger available in Endpoint.ParseMessage - this is expected to be called from Server/Client which have loggers return nil, nil } if len(arr) < 4 { @@ -533,7 +498,7 @@ func (endpoint *Endpoint) CreateCall(request ocpp.Request) (*Call, error) { Action: action, Payload: request, } - if validationEnabled { + if validationEnabled.Load() { err := Validate.Struct(call) if err != nil { return nil, err @@ -556,7 +521,7 @@ func (endpoint *Endpoint) CreateCallResult(confirmation ocpp.Response, uniqueId UniqueId: uniqueId, Payload: confirmation, } - if validationEnabled { + if validationEnabled.Load() { err := Validate.Struct(callResult) if err != nil { return nil, err @@ -574,7 +539,7 @@ func (endpoint *Endpoint) CreateCallError(uniqueId string, code ocpp.ErrorCode, ErrorDescription: description, ErrorDetails: details, } - if validationEnabled { + if validationEnabled.Load() { err := Validate.Struct(callError) if err != nil { return nil, err diff --git a/ocppj/ocppj_test.go b/ocppj/ocppj_test.go index cae20e56..7cb2880c 100644 --- a/ocppj/ocppj_test.go +++ b/ocppj/ocppj_test.go @@ -8,16 +8,15 @@ import ( "testing" ut "github.com/go-playground/universal-translator" + "go.opentelemetry.io/otel/metric/noop" - "github.com/lorenzodonini/ocpp-go/logging" - - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ocppj" - "github.com/lorenzodonini/ocpp-go/ws" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ws" "gopkg.in/go-playground/validator.v9" ) @@ -369,14 +368,17 @@ func (suite *OcppJTestSuite) SetupTest() { mockProfile := ocpp.NewProfile("mock", &MockFeature{}) mockClient := MockWebsocketClient{} mockServer := MockWebsocketServer{} + var err error suite.mockClient = &mockClient suite.mockServer = &mockServer suite.clientRequestQueue = ocppj.NewFIFOClientQueue(queueCapacity) - suite.clientDispatcher = ocppj.NewDefaultClientDispatcher(suite.clientRequestQueue) - suite.chargePoint = ocppj.NewClient("mock_id", suite.mockClient, suite.clientDispatcher, nil, mockProfile) + suite.clientDispatcher = ocppj.NewDefaultClientDispatcher(suite.clientRequestQueue, nil) + suite.chargePoint, err = ocppj.NewClient("mock_id", suite.mockClient, suite.clientDispatcher, nil, nil, mockProfile) + suite.Assert().NoError(err) suite.serverRequestMap = ocppj.NewFIFOQueueMap(queueCapacity) - suite.serverDispatcher = ocppj.NewDefaultServerDispatcher(suite.serverRequestMap) - suite.centralSystem = ocppj.NewServer(suite.mockServer, suite.serverDispatcher, nil, mockProfile) + suite.serverDispatcher = ocppj.NewDefaultServerDispatcher(suite.serverRequestMap, noop.NewMeterProvider(), nil) + suite.centralSystem, err = ocppj.NewServer(suite.mockServer, suite.serverDispatcher, nil, nil, mockProfile) + suite.Assert().NoError(err) defaultDialect := ocpp.V16 // set default to version 1.6 format error *for test only suite.centralSystem.SetDialect(defaultDialect) suite.chargePoint.SetDialect(defaultDialect) @@ -392,91 +394,84 @@ func (suite *OcppJTestSuite) TearDownTest() { } func (suite *OcppJTestSuite) TestGetProfile() { - t := suite.T() profile, ok := suite.chargePoint.GetProfile("mock") - assert.True(t, ok) - assert.NotNil(t, profile) + suite.Assert().True(ok) + suite.Assert().NotNil(profile) feature := profile.GetFeature(MockFeatureName) - assert.NotNil(t, feature) - assert.Equal(t, reflect.TypeOf(MockRequest{}), feature.GetRequestType()) - assert.Equal(t, reflect.TypeOf(MockConfirmation{}), feature.GetResponseType()) + suite.Assert().NotNil(feature) + suite.Assert().Equal(reflect.TypeOf(MockRequest{}), feature.GetRequestType()) + suite.Assert().Equal(reflect.TypeOf(MockConfirmation{}), feature.GetResponseType()) } func (suite *OcppJTestSuite) TestGetProfileForFeature() { - t := suite.T() profile, ok := suite.chargePoint.GetProfileForFeature(MockFeatureName) - assert.True(t, ok) - assert.NotNil(t, profile) - assert.Equal(t, "mock", profile.Name) + suite.Assert().True(ok) + suite.Assert().NotNil(profile) + suite.Assert().Equal("mock", profile.Name) } func (suite *OcppJTestSuite) TestGetProfileForInvalidFeature() { - t := suite.T() profile, ok := suite.chargePoint.GetProfileForFeature("test") - assert.False(t, ok) - assert.Nil(t, profile) + suite.Assert().False(ok) + suite.Assert().Nil(profile) } func (suite *OcppJTestSuite) TestCallMaxValidation() { - t := suite.T() mockLongValue := "somelongvalue" request := newMockRequest(mockLongValue) // Test invalid call call, err := suite.chargePoint.CreateCall(request) - assert.Nil(t, call) - assert.NotNil(t, err) - assert.IsType(t, validator.ValidationErrors{}, err) + suite.Assert().Nil(call) + suite.Assert().NotNil(err) + suite.Assert().IsType(validator.ValidationErrors{}, err) errors := err.(validator.ValidationErrors) - assert.Equal(t, 1, len(errors)) + suite.Assert().Equal(1, len(errors)) validationError := errors[0] - assert.Equal(t, "max", validationError.Tag()) + suite.Assert().Equal("max", validationError.Tag()) } func (suite *OcppJTestSuite) TestCallRequiredValidation() { - t := suite.T() mockLongValue := "" request := newMockRequest(mockLongValue) // Test invalid call call, err := suite.chargePoint.CreateCall(request) - assert.Nil(t, call) - assert.NotNil(t, err) - assert.IsType(t, validator.ValidationErrors{}, err) + suite.Assert().Nil(call) + suite.Assert().NotNil(err) + suite.Assert().IsType(validator.ValidationErrors{}, err) errors := err.(validator.ValidationErrors) - assert.Equal(t, 1, len(errors)) + suite.Assert().Equal(1, len(errors)) validationError := errors[0] - assert.Equal(t, "required", validationError.Tag()) + suite.Assert().Equal("required", validationError.Tag()) } func (suite *OcppJTestSuite) TestCallResultMinValidation() { - t := suite.T() mockShortValue := "val" mockUniqueId := "123456" confirmation := newMockConfirmation(mockShortValue) // Test invalid call callResult, err := suite.chargePoint.CreateCallResult(confirmation, mockUniqueId) - assert.Nil(t, callResult) - assert.NotNil(t, err) - assert.IsType(t, validator.ValidationErrors{}, err) + suite.Assert().Nil(callResult) + suite.Assert().NotNil(err) + suite.Assert().IsType(validator.ValidationErrors{}, err) errors := err.(validator.ValidationErrors) - assert.Equal(t, 1, len(errors)) + suite.Assert().Equal(1, len(errors)) validationError := errors[0] - assert.Equal(t, "min", validationError.Tag()) + suite.Assert().Equal("min", validationError.Tag()) } func (suite *OcppJTestSuite) TestCallResultRequiredValidation() { - t := suite.T() mockShortValue := "" mockUniqueId := "123456" confirmation := newMockConfirmation(mockShortValue) // Test invalid call callResult, err := suite.chargePoint.CreateCallResult(confirmation, mockUniqueId) - assert.Nil(t, callResult) - assert.NotNil(t, err) - assert.IsType(t, validator.ValidationErrors{}, err) + suite.Assert().Nil(callResult) + suite.Assert().NotNil(err) + suite.Assert().IsType(validator.ValidationErrors{}, err) errors := err.(validator.ValidationErrors) - assert.Equal(t, 1, len(errors)) + suite.Assert().Equal(1, len(errors)) validationError := errors[0] - assert.Equal(t, "required", validationError.Tag()) + suite.Assert().Equal("required", validationError.Tag()) } func (suite *OcppJTestSuite) TestCreateCall() { @@ -484,16 +479,16 @@ func (suite *OcppJTestSuite) TestCreateCall() { mockValue := "somevalue" request := newMockRequest(mockValue) call, err := suite.chargePoint.CreateCall(request) - assert.Nil(t, err) + suite.Assert().Nil(err) CheckCall(call, t, MockFeatureName, call.UniqueId) message, ok := call.Payload.(*MockRequest) - assert.True(t, ok) - assert.NotNil(t, message) - assert.Equal(t, mockValue, message.MockValue) + suite.Assert().True(ok) + suite.Assert().NotNil(message) + suite.Assert().Equal(mockValue, message.MockValue) // Check that request was not yet stored as pending request pendingRequest, exists := suite.chargePoint.RequestState.GetPendingRequest(call.UniqueId) - assert.False(t, exists) - assert.Nil(t, pendingRequest) + suite.Assert().False(exists) + suite.Assert().Nil(pendingRequest) } func (suite *OcppJTestSuite) TestCreateCallResult() { @@ -502,12 +497,12 @@ func (suite *OcppJTestSuite) TestCreateCallResult() { mockUniqueId := "123456" confirmation := newMockConfirmation(mockValue) callResult, err := suite.chargePoint.CreateCallResult(confirmation, mockUniqueId) - assert.Nil(t, err) + suite.Assert().Nil(err) CheckCallResult(callResult, t, mockUniqueId) message, ok := callResult.Payload.(*MockConfirmation) - assert.True(t, ok) - assert.NotNil(t, message) - assert.Equal(t, mockValue, message.MockValue) + suite.Assert().True(ok) + suite.Assert().NotNil(message) + suite.Assert().Equal(mockValue, message.MockValue) } func (suite *OcppJTestSuite) TestCreateCallError() { @@ -520,30 +515,28 @@ func (suite *OcppJTestSuite) TestCreateCallError() { } mockDetails := MockDetails{DetailString: mockDetailString} callError, err := suite.chargePoint.CreateCallError(mockUniqueId, ocppj.GenericError, mockDescription, mockDetails) - assert.Nil(t, err) - assert.NotNil(t, callError) + suite.Assert().Nil(err) + suite.Assert().NotNil(callError) CheckCallError(t, callError, mockUniqueId, ocppj.GenericError, mockDescription, mockDetails) } func (suite *OcppJTestSuite) TestParseMessageInvalidLength() { - t := suite.T() mockMessage := make([]interface{}, 2) messageId := "12345" // Test invalid message length mockMessage[0] = ocppj.CALL // Message Type ID mockMessage[1] = messageId // Unique ID message, err := suite.chargePoint.ParseMessage(mockMessage, suite.chargePoint.RequestState) - require.Nil(t, message) - require.Error(t, err) + suite.Require().Nil(message) + suite.Require().Error(err) protoErr := err.(*ocpp.Error) - require.NotNil(t, protoErr) - assert.Equal(t, "", protoErr.MessageId) - assert.Equal(t, ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) - assert.Equal(t, "Invalid message. Expected array length >= 3", protoErr.Description) + suite.Require().NotNil(protoErr) + suite.Assert().Equal("", protoErr.MessageId) + suite.Assert().Equal(ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) + suite.Assert().Equal("Invalid message. Expected array length >= 3", protoErr.Description) } func (suite *OcppJTestSuite) TestParseMessageInvalidTypeId() { - t := suite.T() mockMessage := make([]interface{}, 3) invalidTypeId := "2" messageId := "12345" @@ -551,50 +544,47 @@ func (suite *OcppJTestSuite) TestParseMessageInvalidTypeId() { mockMessage[0] = invalidTypeId // Message Type ID mockMessage[1] = messageId // Unique ID message, err := suite.chargePoint.ParseMessage(mockMessage, suite.chargePoint.RequestState) - require.Nil(t, message) - require.Error(t, err) + suite.Require().Nil(message) + suite.Require().Error(err) protoErr := err.(*ocpp.Error) - require.NotNil(t, protoErr) - assert.Equal(t, "", protoErr.MessageId) - assert.Equal(t, ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) - assert.Equal(t, fmt.Sprintf("Invalid element %v at 0, expected message type (int)", invalidTypeId), protoErr.Description) + suite.Require().NotNil(protoErr) + suite.Assert().Equal("", protoErr.MessageId) + suite.Assert().Equal(ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) + suite.Assert().Equal(fmt.Sprintf("Invalid element %v at 0, expected message type (int)", invalidTypeId), protoErr.Description) } func (suite *OcppJTestSuite) TestParseMessageInvalidMessageId() { - t := suite.T() mockMessage := make([]interface{}, 3) invalidMessageId := 12345 // Test invalid message length mockMessage[0] = float64(ocppj.CALL) // Message Type ID mockMessage[1] = invalidMessageId // Unique ID message, err := suite.chargePoint.ParseMessage(mockMessage, suite.chargePoint.RequestState) - require.Nil(t, message) - require.Error(t, err) + suite.Require().Nil(message) + suite.Require().Error(err) protoErr := err.(*ocpp.Error) - require.NotNil(t, protoErr) - assert.Equal(t, "", protoErr.MessageId) - assert.Equal(t, ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) - assert.Equal(t, fmt.Sprintf("Invalid element %v at 1, expected unique ID (string)", invalidMessageId), protoErr.Description) + suite.Require().NotNil(protoErr) + suite.Assert().Equal("", protoErr.MessageId) + suite.Assert().Equal(ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) + suite.Assert().Equal(fmt.Sprintf("Invalid element %v at 1, expected unique ID (string)", invalidMessageId), protoErr.Description) } func (suite *OcppJTestSuite) TestParseMessageEmptyMessageID() { - t := suite.T() mockMessage := make([]interface{}, 3) // Test invalid message length mockMessage[0] = float64(ocppj.CALL_RESULT) // Message Type ID mockMessage[1] = "" // Empty ID message, err := suite.chargePoint.ParseMessage(mockMessage, suite.chargePoint.RequestState) - require.Nil(t, message) - require.Error(t, err) + suite.Require().Nil(message) + suite.Require().Error(err) protoErr := err.(*ocpp.Error) - require.NotNil(t, protoErr) + suite.Require().NotNil(protoErr) suite.Equal("", protoErr.MessageId) suite.Equal(ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) suite.Errorf(protoErr, "Invalid unique ID, cannot be empty") } func (suite *OcppJTestSuite) TestParseMessageUnknownTypeId() { - t := suite.T() mockMessage := make([]interface{}, 3) messageId := "12345" invalidTypeId := 1 @@ -602,17 +592,16 @@ func (suite *OcppJTestSuite) TestParseMessageUnknownTypeId() { mockMessage[0] = float64(invalidTypeId) // Message Type ID mockMessage[1] = messageId // Unique ID message, err := suite.chargePoint.ParseMessage(mockMessage, suite.chargePoint.RequestState) - require.Nil(t, message) - require.Error(t, err) + suite.Require().Nil(message) + suite.Require().Error(err) protoErr := err.(*ocpp.Error) - require.NotNil(t, protoErr) - assert.Equal(t, messageId, protoErr.MessageId) - assert.Equal(t, ocppj.MessageTypeNotSupported, protoErr.Code) - assert.Equal(t, fmt.Sprintf("Invalid message type ID %v", invalidTypeId), protoErr.Description) + suite.Require().NotNil(protoErr) + suite.Assert().Equal(messageId, protoErr.MessageId) + suite.Assert().Equal(ocppj.MessageTypeNotSupported, protoErr.Code) + suite.Assert().Equal(fmt.Sprintf("Invalid message type ID %v", invalidTypeId), protoErr.Description) } func (suite *OcppJTestSuite) TestParseMessageUnsupported() { - t := suite.T() mockMessage := make([]interface{}, 4) messageId := "12345" invalidAction := "SomeAction" @@ -621,17 +610,16 @@ func (suite *OcppJTestSuite) TestParseMessageUnsupported() { mockMessage[1] = messageId // Unique ID mockMessage[2] = invalidAction // Action message, err := suite.chargePoint.ParseMessage(mockMessage, suite.chargePoint.RequestState) - require.Nil(t, message) - require.Error(t, err) + suite.Require().Nil(message) + suite.Require().Error(err) protoErr := err.(*ocpp.Error) - require.NotNil(t, protoErr) - assert.Equal(t, messageId, protoErr.MessageId) - assert.Equal(t, ocppj.NotSupported, protoErr.Code) - assert.Equal(t, fmt.Sprintf("Unsupported feature %v", invalidAction), protoErr.Description) + suite.Require().NotNil(protoErr) + suite.Assert().Equal(messageId, protoErr.MessageId) + suite.Assert().Equal(ocppj.NotSupported, protoErr.Code) + suite.Assert().Equal(fmt.Sprintf("Unsupported feature %v", invalidAction), protoErr.Description) } func (suite *OcppJTestSuite) TestParseMessageInvalidCall() { - t := suite.T() mockMessage := make([]interface{}, 3) messageId := "12345" // Test invalid message length @@ -639,17 +627,16 @@ func (suite *OcppJTestSuite) TestParseMessageInvalidCall() { mockMessage[1] = messageId // Unique ID mockMessage[2] = MockFeatureName message, err := suite.chargePoint.ParseMessage(mockMessage, suite.chargePoint.RequestState) - require.Nil(t, message) - require.Error(t, err) + suite.Require().Nil(message) + suite.Require().Error(err) protoErr := err.(*ocpp.Error) - require.NotNil(t, protoErr) - assert.Equal(t, messageId, protoErr.MessageId) - assert.Equal(t, ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) - assert.Equal(t, "Invalid Call message. Expected array length 4", protoErr.Description) + suite.Require().NotNil(protoErr) + suite.Assert().Equal(messageId, protoErr.MessageId) + suite.Assert().Equal(ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) + suite.Assert().Equal("Invalid Call message. Expected array length 4", protoErr.Description) } func (suite *OcppJTestSuite) TestParseMessageInvalidActionCall() { - t := suite.T() mockMessage := make([]interface{}, 4) messageId := "12345" mockRequest := newMockRequest("") @@ -659,17 +646,16 @@ func (suite *OcppJTestSuite) TestParseMessageInvalidActionCall() { mockMessage[2] = float64(42) // Wrong type on action parameter mockMessage[3] = mockRequest message, err := suite.chargePoint.ParseMessage(mockMessage, suite.chargePoint.RequestState) - require.Nil(t, message) - require.Error(t, err) + suite.Require().Nil(message) + suite.Require().Error(err) protoErr := err.(*ocpp.Error) - require.NotNil(t, protoErr) - assert.Equal(t, protoErr.MessageId, messageId) // unique id is returned even after invalid type cast error - assert.Equal(t, ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) - assert.Equal(t, "Invalid element 42 at 2, expected action (string)", protoErr.Description) + suite.Require().NotNil(protoErr) + suite.Assert().Equal(protoErr.MessageId, messageId) // unique id is returned even after invalid type cast error + suite.Assert().Equal(ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) + suite.Assert().Equal("Invalid element 42 at 2, expected action (string)", protoErr.Description) } func (suite *OcppJTestSuite) TestParseMessageInvalidCallResult() { - t := suite.T() mockMessage := make([]interface{}, 3) messageId := "12345" mockConfirmation := newMockConfirmation("testValue") @@ -679,12 +665,11 @@ func (suite *OcppJTestSuite) TestParseMessageInvalidCallResult() { mockMessage[2] = mockConfirmation message, err := suite.chargePoint.ParseMessage(mockMessage, suite.chargePoint.RequestState) // Both message and error should be nil - require.Nil(t, message) - require.NoError(t, err) + suite.Require().Nil(message) + suite.Require().NoError(err) } func (suite *OcppJTestSuite) TestParseMessageInvalidCallError() { - t := suite.T() mockMessage := make([]interface{}, 3) messageId := "12345" pendingRequest := newMockRequest("request") @@ -694,17 +679,16 @@ func (suite *OcppJTestSuite) TestParseMessageInvalidCallError() { mockMessage[2] = ocppj.GenericError suite.chargePoint.RequestState.AddPendingRequest(messageId, pendingRequest) // Manually add a pending request, so that response is not rejected message, err := suite.chargePoint.ParseMessage(mockMessage, suite.chargePoint.RequestState) - require.Nil(t, message) - require.Error(t, err) + suite.Require().Nil(message) + suite.Require().Error(err) protoErr := err.(*ocpp.Error) - require.NotNil(t, protoErr) - assert.Equal(t, messageId, protoErr.MessageId) - assert.Equal(t, ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) - assert.Equal(t, "Invalid Call Error message. Expected array length >= 4", protoErr.Description) + suite.Require().NotNil(protoErr) + suite.Assert().Equal(messageId, protoErr.MessageId) + suite.Assert().Equal(ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) + suite.Assert().Equal("Invalid Call Error message. Expected array length >= 4", protoErr.Description) } func (suite *OcppJTestSuite) TestParseMessageInvalidRawErrorCode() { - t := suite.T() mockMessage := make([]interface{}, 5) messageId := "12345" pendingRequest := newMockRequest("request") @@ -715,17 +699,16 @@ func (suite *OcppJTestSuite) TestParseMessageInvalidRawErrorCode() { mockMessage[4] = "error details" suite.chargePoint.RequestState.AddPendingRequest(messageId, pendingRequest) // Manually add a pending request, so that response is not rejected message, err := suite.chargePoint.ParseMessage(mockMessage, suite.chargePoint.RequestState) - require.Nil(t, message) - require.Error(t, err) + suite.Require().Nil(message) + suite.Require().Error(err) protoErr := err.(*ocpp.Error) - require.NotNil(t, protoErr) - assert.Equal(t, protoErr.MessageId, "") // unique id is never set after invalid type cast return - assert.Equal(t, ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) - assert.Equal(t, "Invalid element 42 at 2, expected rawErrorCode (string)", protoErr.Description) + suite.Require().NotNil(protoErr) + suite.Assert().Equal(protoErr.MessageId, "") // unique id is never set after invalid type cast return + suite.Assert().Equal(ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) + suite.Assert().Equal("Invalid element 42 at 2, expected rawErrorCode (string)", protoErr.Description) } func (suite *OcppJTestSuite) TestParseMessageInvalidRequest() { - t := suite.T() mockMessage := make([]interface{}, 4) messageId := "12345" // Test invalid request -> required field missing @@ -735,25 +718,24 @@ func (suite *OcppJTestSuite) TestParseMessageInvalidRequest() { mockMessage[2] = MockFeatureName mockMessage[3] = mockRequest message, err := suite.chargePoint.ParseMessage(mockMessage, suite.chargePoint.RequestState) - require.Nil(t, message) - require.Error(t, err) + suite.Require().Nil(message) + suite.Require().Error(err) protoErr := err.(*ocpp.Error) - require.NotNil(t, protoErr) - assert.Equal(t, messageId, protoErr.MessageId) - assert.Equal(t, ocppj.OccurrenceConstraintErrorType(suite.chargePoint), protoErr.Code) + suite.Require().NotNil(protoErr) + suite.Assert().Equal(messageId, protoErr.MessageId) + suite.Assert().Equal(ocppj.OccurrenceConstraintErrorType(suite.chargePoint), protoErr.Code) // Test invalid request -> max constraint wrong mockRequest.MockValue = "somelongvalue" message, err = suite.chargePoint.ParseMessage(mockMessage, suite.chargePoint.RequestState) - require.Nil(t, message) - require.Error(t, err) + suite.Require().Nil(message) + suite.Require().Error(err) protoErr = err.(*ocpp.Error) - require.NotNil(t, protoErr) - assert.Equal(t, messageId, protoErr.MessageId) - assert.Equal(t, ocppj.PropertyConstraintViolation, protoErr.Code) + suite.Require().NotNil(protoErr) + suite.Assert().Equal(messageId, protoErr.MessageId) + suite.Assert().Equal(ocppj.PropertyConstraintViolation, protoErr.Code) } func (suite *OcppJTestSuite) TestParseMessageInvalidConfirmation() { - t := suite.T() mockMessage := make([]interface{}, 3) messageId := "12345" // Test invalid confirmation -> required field missing @@ -764,26 +746,25 @@ func (suite *OcppJTestSuite) TestParseMessageInvalidConfirmation() { mockMessage[2] = mockConfirmation suite.chargePoint.RequestState.AddPendingRequest(messageId, pendingRequest) // Manually add a pending request, so that response is not rejected message, err := suite.chargePoint.ParseMessage(mockMessage, suite.chargePoint.RequestState) - require.Nil(t, message) - require.Error(t, err) + suite.Require().Nil(message) + suite.Require().Error(err) protoErr := err.(*ocpp.Error) - require.NotNil(t, protoErr) - assert.Equal(t, messageId, protoErr.MessageId) - assert.Equal(t, ocppj.OccurrenceConstraintErrorType(suite.chargePoint), protoErr.Code) + suite.Require().NotNil(protoErr) + suite.Assert().Equal(messageId, protoErr.MessageId) + suite.Assert().Equal(ocppj.OccurrenceConstraintErrorType(suite.chargePoint), protoErr.Code) // Test invalid request -> max constraint wrong mockConfirmation.MockValue = "min" suite.chargePoint.RequestState.AddPendingRequest(messageId, pendingRequest) // Manually add a pending request, so that responses are not rejected message, err = suite.chargePoint.ParseMessage(mockMessage, suite.chargePoint.RequestState) - require.Nil(t, message) - require.Error(t, err) + suite.Require().Nil(message) + suite.Require().Error(err) protoErr = err.(*ocpp.Error) - require.NotNil(t, protoErr) - assert.Equal(t, messageId, protoErr.MessageId) - assert.Equal(t, ocppj.PropertyConstraintViolation, protoErr.Code) + suite.Require().NotNil(protoErr) + suite.Assert().Equal(messageId, protoErr.MessageId) + suite.Assert().Equal(ocppj.PropertyConstraintViolation, protoErr.Code) } func (suite *OcppJTestSuite) TestParseCall() { - t := suite.T() mockMessage := make([]interface{}, 4) messageId := "12345" mockValue := "somevalue" @@ -794,65 +775,16 @@ func (suite *OcppJTestSuite) TestParseCall() { mockMessage[2] = MockFeatureName mockMessage[3] = mockRequest message, protoErr := suite.chargePoint.ParseMessage(mockMessage, suite.chargePoint.RequestState) - assert.Nil(t, protoErr) - assert.NotNil(t, message) - assert.Equal(t, ocppj.CALL, message.GetMessageTypeId()) - assert.Equal(t, messageId, message.GetUniqueId()) - assert.IsType(t, new(ocppj.Call), message) + suite.Assert().Nil(protoErr) + suite.Assert().NotNil(message) + suite.Assert().Equal(ocppj.CALL, message.GetMessageTypeId()) + suite.Assert().Equal(messageId, message.GetUniqueId()) + suite.Assert().IsType(new(ocppj.Call), message) call := message.(*ocppj.Call) - assert.Equal(t, MockFeatureName, call.Action) - assert.IsType(t, new(MockRequest), call.Payload) + suite.Assert().Equal(MockFeatureName, call.Action) + suite.Assert().IsType(new(MockRequest), call.Payload) mockRequest = call.Payload.(*MockRequest) - assert.Equal(t, mockValue, mockRequest.MockValue) -} - -// TODO: implement further ocpp-j protocol tests -type testLogger struct { - c chan string -} - -func (l *testLogger) Debug(args ...interface{}) { - l.c <- "debug" -} - -func (l *testLogger) Debugf(format string, args ...interface{}) { - l.c <- "debugf" -} - -func (l *testLogger) Info(args ...interface{}) { - l.c <- "info" -} - -func (l *testLogger) Infof(format string, args ...interface{}) { - l.c <- "infof" -} - -func (l *testLogger) Error(args ...interface{}) { - l.c <- "error" -} - -func (l *testLogger) Errorf(format string, args ...interface{}) { - l.c <- "errorf" -} - -func (suite *OcppJTestSuite) TestLogger() { - t := suite.T() - logger := testLogger{c: make(chan string, 1)} - // Test with custom logger - ocppj.SetLogger(&logger) - defer ocppj.SetLogger(&logging.VoidLogger{}) - // Expect an error - arr, err := ocppj.ParseRawJsonMessage([]byte("[3,\"1234\",{}]")) - require.NoError(t, err) - _, _ = suite.chargePoint.ParseMessage(arr, suite.chargePoint.RequestState) - s := <-logger.c - assert.Equal(t, "infof", s) - // Nil logger must cause a panic - assertPanic(t, func() { - ocppj.SetLogger(nil) - }, func(r interface{}) { - assert.Equal(t, "cannot set a nil logger", r.(string)) - }) + suite.Assert().Equal(mockValue, mockRequest.MockValue) } type MockValidationError struct { diff --git a/ocppj/queue.go b/ocppj/queue.go index c1f3eeb1..f279bacd 100644 --- a/ocppj/queue.go +++ b/ocppj/queue.go @@ -125,6 +125,12 @@ type ServerQueueMap interface { // Add inserts a new RequestQueue into the map structure. // If such element already exists, it will be replaced with the new queue. Add(clientID string, queue RequestQueue) + + // Size returns the total current number of requests. + Size() int + + // SizePerClient returns the current number of messages per client. + SizePerClient() map[string]int } // FIFOQueueMap is a default implementation of ServerQueueMap. @@ -174,6 +180,30 @@ func (f *FIFOQueueMap) Add(clientID string, queue RequestQueue) { f.data[clientID] = queue } +func (f *FIFOQueueMap) Size() int { + f.mutex.RLock() + defer f.mutex.RUnlock() + + total := 0 + for _, q := range f.data { + total += q.Size() + } + return total +} + +func (f *FIFOQueueMap) SizePerClient() map[string]int { + f.mutex.RLock() + defer f.mutex.RUnlock() + + sizes := map[string]int{} + for clientID, q := range f.data { + sizes[clientID] = q.Size() + } + + return sizes + +} + // NewFIFOQueueMap creates a new FIFOQueueMap, which will automatically create queues with the specified capacity. // // Passing capacity = 0 will generate queues without a maximum capacity. diff --git a/ocppj/queue_bench_test.go b/ocppj/queue_bench_test.go new file mode 100644 index 00000000..1e0f6b59 --- /dev/null +++ b/ocppj/queue_bench_test.go @@ -0,0 +1,403 @@ +package ocppj_test + +import ( + "fmt" + "sync" + "testing" + + "github.com/xBlaz3kx/ocpp-go/ocppj" +) + +// BenchmarkFIFOClientQueue_Push benchmarks pushing elements to the queue +func BenchmarkFIFOClientQueue_Push(b *testing.B) { + queue := ocppj.NewFIFOClientQueue(0) // Unlimited capacity + req := newMockRequest("benchmark") + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = queue.Push(req) + } +} + +// BenchmarkFIFOClientQueue_PushParallel benchmarks concurrent pushes +func BenchmarkFIFOClientQueue_PushParallel(b *testing.B) { + queue := ocppj.NewFIFOClientQueue(0) // Unlimited capacity + req := newMockRequest("benchmark") + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _ = queue.Push(req) + } + }) +} + +// BenchmarkFIFOClientQueue_Pop benchmarks popping elements from the queue +func BenchmarkFIFOClientQueue_Pop(b *testing.B) { + queue := ocppj.NewFIFOClientQueue(0) + req := newMockRequest("benchmark") + + // Pre-populate queue + for i := 0; i < b.N; i++ { + _ = queue.Push(req) + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = queue.Pop() + } +} + +// BenchmarkFIFOClientQueue_PopParallel benchmarks concurrent pops +func BenchmarkFIFOClientQueue_PopParallel(b *testing.B) { + queue := ocppj.NewFIFOClientQueue(0) + req := newMockRequest("benchmark") + + // Pre-populate queue + for i := 0; i < b.N; i++ { + _ = queue.Push(req) + } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _ = queue.Pop() + } + }) +} + +// BenchmarkFIFOClientQueue_Peek benchmarks peeking at the front element +func BenchmarkFIFOClientQueue_Peek(b *testing.B) { + queue := ocppj.NewFIFOClientQueue(0) + req := newMockRequest("benchmark") + _ = queue.Push(req) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = queue.Peek() + } +} + +// BenchmarkFIFOClientQueue_PeekParallel benchmarks concurrent peeks +func BenchmarkFIFOClientQueue_PeekParallel(b *testing.B) { + queue := ocppj.NewFIFOClientQueue(0) + req := newMockRequest("benchmark") + _ = queue.Push(req) + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _ = queue.Peek() + } + }) +} + +// BenchmarkFIFOClientQueue_Size benchmarks getting the queue size +func BenchmarkFIFOClientQueue_Size(b *testing.B) { + queue := ocppj.NewFIFOClientQueue(0) + req := newMockRequest("benchmark") + for i := 0; i < 1000; i++ { + _ = queue.Push(req) + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = queue.Size() + } +} + +// BenchmarkFIFOClientQueue_SizeParallel benchmarks concurrent size checks +func BenchmarkFIFOClientQueue_SizeParallel(b *testing.B) { + queue := ocppj.NewFIFOClientQueue(0) + req := newMockRequest("benchmark") + for i := 0; i < 1000; i++ { + _ = queue.Push(req) + } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _ = queue.Size() + } + }) +} + +// BenchmarkFIFOClientQueue_IsEmpty benchmarks checking if queue is empty +func BenchmarkFIFOClientQueue_IsEmpty(b *testing.B) { + queue := ocppj.NewFIFOClientQueue(0) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = queue.IsEmpty() + } +} + +// BenchmarkFIFOClientQueue_IsFull benchmarks checking if queue is full +func BenchmarkFIFOClientQueue_IsFull(b *testing.B) { + capacity := 1000 + queue := ocppj.NewFIFOClientQueue(capacity) + req := newMockRequest("benchmark") + for i := 0; i < capacity; i++ { + _ = queue.Push(req) + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = queue.IsFull() + } +} + +// BenchmarkFIFOClientQueue_PushPop benchmarks the push-pop cycle +func BenchmarkFIFOClientQueue_PushPop(b *testing.B) { + queue := ocppj.NewFIFOClientQueue(0) + req := newMockRequest("benchmark") + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = queue.Push(req) + _ = queue.Pop() + } +} + +// BenchmarkFIFOClientQueue_PushPopParallel benchmarks concurrent push-pop operations +func BenchmarkFIFOClientQueue_PushPopParallel(b *testing.B) { + queue := ocppj.NewFIFOClientQueue(0) + req := newMockRequest("benchmark") + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _ = queue.Push(req) + _ = queue.Pop() + } + }) +} + +// BenchmarkFIFOClientQueue_MixedOperations benchmarks mixed operations +func BenchmarkFIFOClientQueue_MixedOperations(b *testing.B) { + queue := ocppj.NewFIFOClientQueue(1000) + req := newMockRequest("benchmark") + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = queue.Push(req) + _ = queue.Peek() + _ = queue.Size() + _ = queue.IsEmpty() + if i%2 == 0 { + _ = queue.Pop() + } + } +} + +// BenchmarkFIFOQueueMap_Get benchmarks getting a queue from the map +func BenchmarkFIFOQueueMap_Get(b *testing.B) { + queueMap := ocppj.NewFIFOQueueMap(100) + clientID := "client1" + queueMap.GetOrCreate(clientID) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _ = queueMap.Get(clientID) + } +} + +// BenchmarkFIFOQueueMap_GetParallel benchmarks concurrent gets +func BenchmarkFIFOQueueMap_GetParallel(b *testing.B) { + queueMap := ocppj.NewFIFOQueueMap(100) + clientID := "client1" + queueMap.GetOrCreate(clientID) + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _, _ = queueMap.Get(clientID) + } + }) +} + +// BenchmarkFIFOQueueMap_GetOrCreate benchmarks getting or creating a queue +func BenchmarkFIFOQueueMap_GetOrCreate(b *testing.B) { + queueMap := ocppj.NewFIFOQueueMap(100) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + clientID := fmt.Sprintf("client%d", i%10) // Reuse 10 clients + _ = queueMap.GetOrCreate(clientID) + } +} + +// BenchmarkFIFOQueueMap_GetOrCreateParallel benchmarks concurrent get-or-create operations +func BenchmarkFIFOQueueMap_GetOrCreateParallel(b *testing.B) { + queueMap := ocppj.NewFIFOQueueMap(100) + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + i := 0 + for pb.Next() { + clientID := fmt.Sprintf("client%d", i%10) // Reuse 10 clients + _ = queueMap.GetOrCreate(clientID) + i++ + } + }) +} + +// BenchmarkFIFOQueueMap_Add benchmarks adding a queue to the map +func BenchmarkFIFOQueueMap_Add(b *testing.B) { + queueMap := ocppj.NewFIFOQueueMap(100) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + clientID := fmt.Sprintf("client%d", i) + queue := ocppj.NewFIFOClientQueue(100) + queueMap.Add(clientID, queue) + } +} + +// BenchmarkFIFOQueueMap_Remove benchmarks removing a queue from the map +func BenchmarkFIFOQueueMap_Remove(b *testing.B) { + queueMap := ocppj.NewFIFOQueueMap(100) + + // Pre-populate map + for i := 0; i < b.N; i++ { + clientID := fmt.Sprintf("client%d", i) + queueMap.GetOrCreate(clientID) + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + clientID := fmt.Sprintf("client%d", i) + queueMap.Remove(clientID) + } +} + +// BenchmarkFIFOQueueMap_Size benchmarks getting total size across all queues +func BenchmarkFIFOQueueMap_Size(b *testing.B) { + queueMap := ocppj.NewFIFOQueueMap(100) + req := newMockRequest("benchmark") + + // Pre-populate with queues and elements + for i := 0; i < 100; i++ { + clientID := fmt.Sprintf("client%d", i) + queue := queueMap.GetOrCreate(clientID) + for j := 0; j < 10; j++ { + _ = queue.Push(req) + } + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = queueMap.Size() + } +} + +// BenchmarkFIFOQueueMap_SizeParallel benchmarks concurrent size checks +func BenchmarkFIFOQueueMap_SizeParallel(b *testing.B) { + queueMap := ocppj.NewFIFOQueueMap(100) + req := newMockRequest("benchmark") + + // Pre-populate with queues and elements + for i := 0; i < 100; i++ { + clientID := fmt.Sprintf("client%d", i) + queue := queueMap.GetOrCreate(clientID) + for j := 0; j < 10; j++ { + _ = queue.Push(req) + } + } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _ = queueMap.Size() + } + }) +} + +// BenchmarkFIFOQueueMap_SizePerClient benchmarks getting size per client +func BenchmarkFIFOQueueMap_SizePerClient(b *testing.B) { + queueMap := ocppj.NewFIFOQueueMap(100) + req := newMockRequest("benchmark") + + // Pre-populate with queues and elements + for i := 0; i < 100; i++ { + clientID := fmt.Sprintf("client%d", i) + queue := queueMap.GetOrCreate(clientID) + for j := 0; j < 10; j++ { + _ = queue.Push(req) + } + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = queueMap.SizePerClient() + } +} + +// BenchmarkFIFOQueueMap_SizePerClientParallel benchmarks concurrent size-per-client checks +func BenchmarkFIFOQueueMap_SizePerClientParallel(b *testing.B) { + queueMap := ocppj.NewFIFOQueueMap(100) + req := newMockRequest("benchmark") + + // Pre-populate with queues and elements + for i := 0; i < 100; i++ { + clientID := fmt.Sprintf("client%d", i) + queue := queueMap.GetOrCreate(clientID) + for j := 0; j < 10; j++ { + _ = queue.Push(req) + } + } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _ = queueMap.SizePerClient() + } + }) +} + +// BenchmarkFIFOQueueMap_MixedOperations benchmarks mixed map operations +func BenchmarkFIFOQueueMap_MixedOperations(b *testing.B) { + queueMap := ocppj.NewFIFOQueueMap(100) + req := newMockRequest("benchmark") + + b.ResetTimer() + for i := 0; i < b.N; i++ { + clientID := fmt.Sprintf("client%d", i%10) + queue := queueMap.GetOrCreate(clientID) + _ = queue.Push(req) + _ = queueMap.Size() + if i%5 == 0 { + queueMap.Remove(clientID) + } + } +} + +// BenchmarkFIFOQueueMap_ConcurrentClients benchmarks concurrent operations on different clients +func BenchmarkFIFOQueueMap_ConcurrentClients(b *testing.B) { + queueMap := ocppj.NewFIFOQueueMap(100) + req := newMockRequest("benchmark") + numClients := 10 + + // Pre-create clients + for i := 0; i < numClients; i++ { + clientID := fmt.Sprintf("client%d", i) + queueMap.GetOrCreate(clientID) + } + + b.ResetTimer() + var wg sync.WaitGroup + for i := 0; i < numClients; i++ { + wg.Add(1) + go func(clientID string) { + defer wg.Done() + for j := 0; j < b.N/numClients; j++ { + queue, _ := queueMap.Get(clientID) + if queue != nil { + _ = queue.Push(req) + _ = queue.Pop() + } + } + }(fmt.Sprintf("client%d", i)) + } + wg.Wait() +} diff --git a/ocppj/queue_test.go b/ocppj/queue_test.go index c12f9853..18150a39 100644 --- a/ocppj/queue_test.go +++ b/ocppj/queue_test.go @@ -1,10 +1,8 @@ package ocppj_test import ( - "github.com/lorenzodonini/ocpp-go/ocppj" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "github.com/xBlaz3kx/ocpp-go/ocppj" ) const queueCapacity = 10 @@ -19,104 +17,96 @@ func (suite *ClientQueueTestSuite) SetupTest() { } func (suite *ClientQueueTestSuite) TestQueueEmpty() { - t := suite.T() empty := suite.queue.IsEmpty() - assert.True(t, empty) + suite.Assert().True(empty) } func (suite *ClientQueueTestSuite) TestPushElement() { - t := suite.T() req := newMockRequest("somevalue") err := suite.queue.Push(req) - require.Nil(t, err) - assert.False(t, suite.queue.IsEmpty()) - assert.False(t, suite.queue.IsFull()) - assert.Equal(t, 1, suite.queue.Size()) + suite.Require().Nil(err) + suite.Assert().False(suite.queue.IsEmpty()) + suite.Assert().False(suite.queue.IsFull()) + suite.Assert().Equal(1, suite.queue.Size()) } func (suite *ClientQueueTestSuite) TestQueueSize() { - t := suite.T() for i := 0; i < queueCapacity; i++ { req := newMockRequest("somevalue") err := suite.queue.Push(req) - require.Nil(t, err) - assert.False(t, suite.queue.IsEmpty()) - assert.Equal(t, i+1, suite.queue.Size()) + suite.Require().Nil(err) + suite.Assert().False(suite.queue.IsEmpty()) + suite.Assert().Equal(i+1, suite.queue.Size()) } } func (suite *ClientQueueTestSuite) TestQueueFull() { - t := suite.T() for i := 0; i < queueCapacity+2; i++ { req := newMockRequest("somevalue") err := suite.queue.Push(req) if i < queueCapacity { - require.Nil(t, err) + suite.Require().Nil(err) if i < queueCapacity-1 { - assert.False(t, suite.queue.IsFull()) + suite.Assert().False(suite.queue.IsFull()) } else { - assert.True(t, suite.queue.IsFull()) + suite.Assert().True(suite.queue.IsFull()) } } else { - require.NotNil(t, err) - assert.True(t, suite.queue.IsFull()) + suite.Require().NotNil(err) + suite.Assert().True(suite.queue.IsFull()) } } } func (suite *ClientQueueTestSuite) TestPeekElement() { - t := suite.T() req := newMockRequest("somevalue") err := suite.queue.Push(req) - require.Nil(t, err) + suite.Require().Nil(err) el := suite.queue.Peek() - require.NotNil(t, el) + suite.Require().NotNil(el) peeked, ok := el.(*MockRequest) - require.True(t, ok) - require.NotNil(t, peeked) - assert.Equal(t, req.MockValue, peeked.MockValue) - assert.False(t, suite.queue.IsEmpty()) - assert.False(t, suite.queue.IsFull()) - assert.Equal(t, 1, suite.queue.Size()) + suite.Require().True(ok) + suite.Require().NotNil(peeked) + suite.Assert().Equal(req.MockValue, peeked.MockValue) + suite.Assert().False(suite.queue.IsEmpty()) + suite.Assert().False(suite.queue.IsFull()) + suite.Assert().Equal(1, suite.queue.Size()) } func (suite *ClientQueueTestSuite) TestPopElement() { - t := suite.T() req := newMockRequest("somevalue") err := suite.queue.Push(req) - require.Nil(t, err) + suite.Require().Nil(err) el := suite.queue.Pop() - require.NotNil(t, el) + suite.Require().NotNil(el) popped, ok := el.(*MockRequest) - require.True(t, ok) - require.NotNil(t, popped) - assert.Equal(t, req.MockValue, popped.MockValue) - assert.True(t, suite.queue.IsEmpty()) - assert.False(t, suite.queue.IsFull()) + suite.Require().True(ok) + suite.Require().NotNil(popped) + suite.Assert().Equal(req.MockValue, popped.MockValue) + suite.Assert().True(suite.queue.IsEmpty()) + suite.Assert().False(suite.queue.IsFull()) } func (suite *ClientQueueTestSuite) TestQueueNoCapacity() { - t := suite.T() suite.queue = ocppj.NewFIFOClientQueue(0) for i := 0; i < 50; i++ { req := newMockRequest("somevalue") err := suite.queue.Push(req) - require.Nil(t, err) + suite.Require().Nil(err) } - assert.False(t, suite.queue.IsFull()) + suite.Assert().False(suite.queue.IsFull()) } func (suite *ClientQueueTestSuite) TestQueueClear() { - t := suite.T() for i := 0; i < queueCapacity; i++ { req := newMockRequest("somevalue") err := suite.queue.Push(req) - require.Nil(t, err) + suite.Require().Nil(err) } - assert.True(t, suite.queue.IsFull()) + suite.Assert().True(suite.queue.IsFull()) suite.queue.Init() - assert.True(t, suite.queue.IsEmpty()) - assert.Equal(t, 0, suite.queue.Size()) + suite.Assert().True(suite.queue.IsEmpty()) + suite.Assert().Equal(0, suite.queue.Size()) } type ServerQueueMapTestSuite struct { @@ -129,7 +119,6 @@ func (suite *ServerQueueMapTestSuite) SetupTest() { } func (suite *ServerQueueMapTestSuite) TestAddElement() { - t := suite.T() q := ocppj.NewFIFOClientQueue(0) el := "element1" _ = q.Push(el) @@ -137,37 +126,66 @@ func (suite *ServerQueueMapTestSuite) TestAddElement() { suite.queueMap.Add(id, q) retrieved, ok := suite.queueMap.Get(id) - require.True(t, ok) - require.NotNil(t, retrieved) - assert.False(t, retrieved.IsEmpty()) - assert.Equal(t, 1, retrieved.Size()) - assert.Equal(t, el, retrieved.Peek()) + suite.Require().True(ok) + suite.Require().NotNil(retrieved) + suite.Assert().False(retrieved.IsEmpty()) + suite.Assert().Equal(1, retrieved.Size()) + suite.Assert().Equal(el, retrieved.Peek()) } func (suite *ServerQueueMapTestSuite) TestGetOrCreate() { - t := suite.T() el := "element1" id := "test" q, ok := suite.queueMap.Get(id) - require.False(t, ok) - require.Nil(t, q) + suite.Require().False(ok) + suite.Require().Nil(q) q = suite.queueMap.GetOrCreate(id) - require.NotNil(t, q) + suite.Require().NotNil(q) _ = q.Push(el) // Verify consistency q, ok = suite.queueMap.Get(id) - require.True(t, ok) - assert.Equal(t, 1, q.Size()) - assert.Equal(t, el, q.Peek()) + suite.Require().True(ok) + suite.Assert().Equal(1, q.Size()) + suite.Assert().Equal(el, q.Peek()) } func (suite *ServerQueueMapTestSuite) TestRemove() { - t := suite.T() id := "test" q := suite.queueMap.GetOrCreate(id) - require.NotNil(t, q) + suite.Require().NotNil(q) suite.queueMap.Remove(id) q, ok := suite.queueMap.Get(id) - assert.False(t, ok) - assert.Nil(t, q) + suite.Assert().False(ok) + suite.Assert().Nil(q) +} + +func (suite *ServerQueueMapTestSuite) TestSize() { + suite.Equal(0, suite.queueMap.Size()) + id := "test" + q := suite.queueMap.GetOrCreate(id) + suite.NotNil(q) + err := q.Push("something") + suite.NoError(err) + suite.Equal(1, suite.queueMap.Size()) + suite.queueMap.Remove(id) + suite.Equal(0, suite.queueMap.Size()) +} + +func (suite *ServerQueueMapTestSuite) TestSizePerClient() { + for i := 0; i < queueCapacity; i++ { + id := "client" + string(rune(i%3+'A')) // Three different clients: A, B, C + q := suite.queueMap.GetOrCreate(id) + suite.NotNil(q) + req := newMockRequest("somevalue") + err := q.Push(req) + suite.Nil(err) + } + + expectedMap := map[string]int{ + "clientA": 4, + "clientB": 3, + "clientC": 3, + } + + suite.Equal(expectedMap, suite.queueMap.SizePerClient()) } diff --git a/ocppj/server.go b/ocppj/server.go index 2b0365da..b8ebc55a 100644 --- a/ocppj/server.go +++ b/ocppj/server.go @@ -1,19 +1,23 @@ package ocppj import ( - "errors" + "context" "fmt" + "time" + "github.com/pkg/errors" + "github.com/xBlaz3kx/ocpp-go/logging" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ws" + "go.opentelemetry.io/otel" "gopkg.in/go-playground/validator.v9" - - "github.com/lorenzodonini/ocpp-go/ocpp" - "github.com/lorenzodonini/ocpp-go/ws" ) // The endpoint waiting for incoming connections from OCPP clients, in an OCPP-J topology. // During message exchange, the two roles may be reversed (depending on the message direction), but a server struct remains associated to a central system. type Server struct { Endpoint + logger logging.Logger server ws.Server checkClientHandler ws.CheckClientHandler newClientHandler ClientHandler @@ -24,6 +28,7 @@ type Server struct { invalidMessageHook InvalidMessageHook dispatcher ServerDispatcher RequestState ServerState + metrics *ocppMetrics } type ClientHandler func(client ws.Channel) @@ -41,10 +46,28 @@ type InvalidMessageHook func(client ws.Channel, err *ocpp.Error, rawJson string, // s := ocppj.NewServer(ws.NewServer(), nil, nil) // // The dispatcher's associated ClientState will be set during initialization. -func NewServer(wsServer ws.Server, dispatcher ServerDispatcher, stateHandler ServerState, profiles ...*ocpp.Profile) *Server { +func NewServer( + wsServer ws.Server, + dispatcher ServerDispatcher, + stateHandler ServerState, + logger logging.Logger, + profiles ...*ocpp.Profile, +) (*Server, error) { + if logger == nil { + logger = &logging.VoidLogger{} + } + + meterProvider := otel.GetMeterProvider() + metrics, err := newOcppServerMetrics(meterProvider, "") + if err != nil { + return nil, errors.New("failed to create OCPP metrics") + } + + // Create default dispatcher and state handler if not provided if dispatcher == nil { - dispatcher = NewDefaultServerDispatcher(NewFIFOQueueMap(0)) + dispatcher = NewDefaultServerDispatcher(NewFIFOQueueMap(0), meterProvider, logger) } + if stateHandler == nil { d, ok := dispatcher.(*DefaultServerDispatcher) if !ok { @@ -53,18 +76,28 @@ func NewServer(wsServer ws.Server, dispatcher ServerDispatcher, stateHandler Ser stateHandler = d.pendingRequestState } } + if wsServer == nil { wsServer = ws.NewServer() } + dispatcher.SetNetworkServer(wsServer) dispatcher.SetPendingRequestState(stateHandler) // Create server and add profiles - s := Server{Endpoint: Endpoint{}, server: wsServer, RequestState: stateHandler, dispatcher: dispatcher} + s := Server{ + logger: logger, + Endpoint: Endpoint{}, + server: wsServer, + RequestState: stateHandler, + dispatcher: dispatcher, + metrics: metrics, + } for _, profile := range profiles { s.AddProfile(profile) } - return &s + + return &s, nil } // Registers a handler for incoming requests. @@ -160,20 +193,35 @@ func (s *Server) SendRequest(clientID string, request ocpp.Request) error { if !s.dispatcher.IsRunning() { return fmt.Errorf("ocppj server is not started, couldn't send request") } + + var metricErr *ocppMetricsError + defer func() { + // Report a metric after request was sent. + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + s.metrics.IncrementOutboundRequests(ctx, clientID, request.GetFeatureName(), metricErr) + }() + call, err := s.CreateCall(request) if err != nil { + metricErr = &payloadError // Could also be a val return err } + jsonMessage, err := call.MarshalJSON() if err != nil { + metricErr = &payloadError return err } + // Will not send right away. Queuing message and let it be processed by dedicated requestPump routine if err = s.dispatcher.SendRequest(clientID, RequestBundle{call, jsonMessage}); err != nil { - log.Errorf("error dispatching request [%s, %s] to %s: %v", call.UniqueId, call.Action, clientID, err) + metricErr = &metricsNetworkError + s.logger.Errorf("error dispatching request [%s, %s] to %s: %v", call.UniqueId, call.Action, clientID, err) return err } - log.Debugf("enqueued CALL [%s, %s] for %s", call.UniqueId, call.Action, clientID) + + s.logger.Debugf("enqueued CALL [%s, %s] for %s", call.UniqueId, call.Action, clientID) return nil } @@ -197,11 +245,11 @@ func (s *Server) SendResponse(clientID string, requestId string, response ocpp.R return ocpp.NewError(GenericError, err.Error(), requestId) } if err = s.server.Write(clientID, jsonMessage); err != nil { - log.Errorf("error sending response [%s] to %s: %v", callResult.GetUniqueId(), clientID, err) + s.logger.Errorf("error sending response [%s] to %s: %v", callResult.GetUniqueId(), clientID, err) return ocpp.NewError(GenericError, err.Error(), requestId) } - log.Debugf("sent CALL RESULT [%s] for %s", callResult.GetUniqueId(), clientID) - log.Debugf("sent JSON message to %s: %s", clientID, string(jsonMessage)) + s.logger.Debugf("sent CALL RESULT [%s] for %s", callResult.GetUniqueId(), clientID) + s.logger.Debugf("sent JSON message to %s: %s", clientID, string(jsonMessage)) return nil } @@ -223,25 +271,31 @@ func (s *Server) SendError(clientID string, requestId string, errorCode ocpp.Err return ocpp.NewError(GenericError, err.Error(), requestId) } if err = s.server.Write(clientID, jsonMessage); err != nil { - log.Errorf("error sending response error [%s] to %s: %v", callError.UniqueId, clientID, err) + s.logger.Errorf("error sending response error [%s] to %s: %v", callError.UniqueId, clientID, err) return ocpp.NewError(GenericError, err.Error(), requestId) } - log.Debugf("sent CALL ERROR [%s] for %s", callError.UniqueId, clientID) - log.Debugf("sent JSON message to %s: %s", clientID, string(jsonMessage)) + s.logger.Debugf("sent CALL ERROR [%s] for %s", callError.UniqueId, clientID) + s.logger.Debugf("sent JSON message to %s: %s", clientID, string(jsonMessage)) return nil } func (s *Server) ocppMessageHandler(wsChannel ws.Channel, data []byte) error { + metricCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + parsedJson, err := ParseRawJsonMessage(data) if err != nil { - log.Error(err) + s.metrics.IncrementOutboundRequests(metricCtx, wsChannel.ID(), "", &payloadError) + s.logger.Error(err) return err } - log.Debugf("received JSON message from %s: %s", wsChannel.ID(), string(data)) + + s.logger.Debugf("received JSON message from %s: %s", wsChannel.ID(), string(data)) // Get pending requests for client pending := s.RequestState.GetClientState(wsChannel.ID()) message, err := s.ParseMessage(parsedJson, pending) if err != nil { + s.metrics.IncrementOutboundRequests(metricCtx, wsChannel.ID(), "", &validationError) ocppErr := err.(*ocpp.Error) messageID := ocppErr.MessageId // Support ad-hoc callback for invalid message handling @@ -261,31 +315,34 @@ func (s *Server) ocppMessageHandler(wsChannel ws.Channel, data []byte) error { return err2 } } - log.Error(err) + s.logger.Error(err) return err } if message != nil { switch message.GetMessageTypeId() { case CALL: call := message.(*Call) - log.Debugf("handling incoming CALL [%s, %s] from %s", call.UniqueId, call.Action, wsChannel.ID()) + s.logger.Debugf("handling incoming CALL [%s, %s] from %s", call.UniqueId, call.Action, wsChannel.ID()) if s.requestHandler != nil { s.requestHandler(wsChannel, call.Payload, call.UniqueId, call.Action) } + s.metrics.IncrementInboundRequests(metricCtx, wsChannel.ID(), call.Payload.GetFeatureName(), nil) case CALL_RESULT: callResult := message.(*CallResult) - log.Debugf("handling incoming CALL RESULT [%s] from %s", callResult.UniqueId, wsChannel.ID()) + s.logger.Debugf("handling incoming CALL RESULT [%s] from %s", callResult.UniqueId, wsChannel.ID()) s.dispatcher.CompleteRequest(wsChannel.ID(), callResult.GetUniqueId()) if s.responseHandler != nil { s.responseHandler(wsChannel, callResult.Payload, callResult.UniqueId) } + s.metrics.IncrementOutboundRequests(metricCtx, wsChannel.ID(), callResult.Payload.GetFeatureName(), nil) case CALL_ERROR: callError := message.(*CallError) - log.Debugf("handling incoming CALL RESULT [%s] from %s", callError.UniqueId, wsChannel.ID()) + s.logger.Debugf("handling incoming CALL ERROR [%s] from %s", callError.UniqueId, wsChannel.ID()) s.dispatcher.CompleteRequest(wsChannel.ID(), callError.GetUniqueId()) if s.errorHandler != nil { s.errorHandler(wsChannel, ocpp.NewError(callError.ErrorCode, callError.ErrorDescription, callError.UniqueId), callError.ErrorDetails) } + // todo add metric for error } } return nil @@ -299,7 +356,7 @@ func (s *Server) ocppMessageHandler(wsChannel ws.Channel, data []byte) error { // The method will, however, only attempt to send a default error once. // If this operation fails, the other endpoint may still starve. func (s *Server) HandleFailedResponseError(clientID string, requestID string, err error, featureName string) { - log.Debugf("handling error for failed response [%s]", requestID) + s.logger.Debugf("handling error for failed response [%s]", requestID) var responseErr *ocpp.Error // There's several possible errors: invalid profile, invalid payload or send error switch err.(type) { diff --git a/ocppj/server_metrics.go b/ocppj/server_metrics.go new file mode 100644 index 00000000..a988552a --- /dev/null +++ b/ocppj/server_metrics.go @@ -0,0 +1,109 @@ +package ocppj + +import ( + "context" + "fmt" + + "github.com/pkg/errors" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" +) + +const ( + requestsInboundMetric = "ocpp_requests_inbound" + requestsOutboundMetric = "ocpp_requests_outbound" +) + +const ( + attributeChargePointId = "charge_point_id" + attributeOcppVersion = "ocpp_version" + attributeFeature = "feature" + attributeError = "error" +) + +type ocppMetricsError string + +var ( + chargePointError = ocppMetricsError("charge_point_error") + metricsInternalError = ocppMetricsError("internal_error") + metricsNetworkError = ocppMetricsError("network_error") + payloadError = ocppMetricsError("payload_error") + validationError = ocppMetricsError("validation_error") +) + +type ocppMetrics struct { + requestsIn metric.Int64Histogram + requestsOut metric.Int64Histogram + meter metric.Meter +} + +// newOcppServerMetrics Creates a new metrics instance +func newOcppServerMetrics(meterProvider metric.MeterProvider, ocppVersion string) (*ocppMetrics, error) { + if meterProvider == nil { + return nil, errors.New("meterProvider is required") + } + + meter := meterProvider.Meter( + "ocpp", + metric.WithInstrumentationAttributes(attribute.String(attributeOcppVersion, ocppVersion)), + ) + + requestsIn, err := meter.Int64Histogram( + requestsInboundMetric, + metric.WithDescription("Number of inbound requests"), + ) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("failed to create %s metric", requestsInboundMetric)) + } + + requestsOut, err := meter.Int64Histogram( + requestsOutboundMetric, + metric.WithDescription("Number of outbound requests"), + ) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("failed to create %s metric", requestsOutboundMetric)) + } + + metrics := &ocppMetrics{ + requestsIn: requestsIn, + requestsOut: requestsOut, + meter: meter, + } + return metrics, nil +} + +func (m *ocppMetrics) IncrementInboundRequests(ctx context.Context, chargePointId, requestName string, error *ocppMetricsError) { + attrs := []attribute.KeyValue{ + attribute.String(attributeChargePointId, chargePointId), + } + + // Optionally add a request name. Should be present most of the time, except when we cannot unmarshal the request. + if requestName != "" { + attribute.String(attributeFeature, requestName) + } + + if error != nil { + attrs = append(attrs, attribute.String(attributeError, string(*error))) + } + + metricAttrs := metric.WithAttributes(attrs...) + m.requestsIn.Record(ctx, 1, metricAttrs) +} + +func (m *ocppMetrics) IncrementOutboundRequests(ctx context.Context, chargePointId, requestName string, error *ocppMetricsError) { + attrs := []attribute.KeyValue{ + attribute.String(attributeChargePointId, chargePointId), + } + + // Optionally add a request name. Should be present most of the time, except when we cannot unmarshal the request. + if requestName != "" { + attribute.String(attributeFeature, requestName) + } + + if error != nil { + attrs = append(attrs, attribute.String(attributeError, string(*error))) + } + + metricAttrs := metric.WithAttributes(attrs...) + m.requestsOut.Record(ctx, 1, metricAttrs) +} diff --git a/ocppj/state.go b/ocppj/state.go index 17b11743..f9e0d0bc 100644 --- a/ocppj/state.go +++ b/ocppj/state.go @@ -3,7 +3,7 @@ package ocppj import ( "sync" - "github.com/lorenzodonini/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocpp" ) // Contains the pending request state for messages, associated to a single client-server channel. @@ -57,8 +57,8 @@ func (s *clientState) AddPendingRequest(requestID string, req ocpp.Request) { } func (s *clientState) GetPendingRequest(requestID string) (ocpp.Request, bool) { - s.mutex.Lock() - defer s.mutex.Unlock() + s.mutex.RLock() + defer s.mutex.RUnlock() if s.requestID != requestID { return nil, false } @@ -81,8 +81,8 @@ func (s *clientState) ClearPendingRequests() { } func (s *clientState) HasPendingRequest() bool { - s.mutex.Lock() - defer s.mutex.Unlock() + s.mutex.RLock() + defer s.mutex.RUnlock() return s.requestID != "" } @@ -173,8 +173,8 @@ func (d *serverState) GetClientState(clientID string) ClientState { func (d *serverState) HasPendingRequest(clientID string) bool { if d.mutex != nil { - d.mutex.Lock() - defer d.mutex.Unlock() + d.mutex.RLock() + defer d.mutex.RUnlock() } state, exists := d.pendingRequestState[clientID] return exists && state.HasPendingRequest() @@ -182,8 +182,8 @@ func (d *serverState) HasPendingRequest(clientID string) bool { func (d *serverState) HasPendingRequests() bool { if d.mutex != nil { - d.mutex.Lock() - defer d.mutex.Unlock() + d.mutex.RLock() + defer d.mutex.RUnlock() } for _, s := range d.pendingRequestState { if s.HasPendingRequest() { diff --git a/ocppj/state_test.go b/ocppj/state_test.go index 8f98ffa2..15c65be1 100644 --- a/ocppj/state_test.go +++ b/ocppj/state_test.go @@ -3,11 +3,9 @@ package ocppj_test import ( "sync" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" - "github.com/lorenzodonini/ocpp-go/ocppj" + "github.com/xBlaz3kx/ocpp-go/ocppj" ) type ClientStateTestSuite struct { @@ -20,33 +18,30 @@ func (suite *ClientStateTestSuite) SetupTest() { } func (suite *ClientStateTestSuite) TestAddPendingRequest() { - t := suite.T() requestID := "1234" req := newMockRequest("somevalue") - require.False(t, suite.state.HasPendingRequest()) + suite.Require().False(suite.state.HasPendingRequest()) suite.state.AddPendingRequest(requestID, req) - require.True(t, suite.state.HasPendingRequest()) + suite.Require().True(suite.state.HasPendingRequest()) r, exists := suite.state.GetPendingRequest(requestID) - assert.True(t, exists) - assert.Equal(t, req, r) + suite.Assert().True(exists) + suite.Assert().Equal(req, r) } func (suite *ClientStateTestSuite) TestGetInvalidPendingRequest() { - t := suite.T() requestID := "1234" suite.state.AddPendingRequest(requestID, newMockRequest("somevalue")) - require.True(t, suite.state.HasPendingRequest()) + suite.Require().True(suite.state.HasPendingRequest()) invalidRequestIDs := []string{"4321", "5678", "1230", "deadc0de"} // Nothing returned when querying for an unknown request ID for _, id := range invalidRequestIDs { r, exists := suite.state.GetPendingRequest(id) - assert.False(t, exists) - assert.Nil(t, r) + suite.Assert().False(exists) + suite.Assert().Nil(r) } } func (suite *ClientStateTestSuite) TestAddMultiplePendingRequests() { - t := suite.T() requestId1 := "1234" requestId2 := "5678" req1 := newMockRequest("somevalue1") @@ -54,53 +49,50 @@ func (suite *ClientStateTestSuite) TestAddMultiplePendingRequests() { suite.state.AddPendingRequest(requestId1, req1) suite.state.AddPendingRequest(requestId2, req2) r, exists := suite.state.GetPendingRequest(requestId1) - assert.True(t, exists) - assert.NotNil(t, r) + suite.Assert().True(exists) + suite.Assert().NotNil(r) r, exists = suite.state.GetPendingRequest(requestId2) - assert.False(t, exists) - assert.Nil(t, r) + suite.Assert().False(exists) + suite.Assert().Nil(r) } func (suite *ClientStateTestSuite) TestDeletePendingRequest() { - t := suite.T() requestID := "1234" req := newMockRequest("somevalue") suite.state.AddPendingRequest(requestID, req) - require.True(t, suite.state.HasPendingRequest()) + suite.Require().True(suite.state.HasPendingRequest()) suite.state.DeletePendingRequest(requestID) // Previously added request is gone - assert.False(t, suite.state.HasPendingRequest()) + suite.Assert().False(suite.state.HasPendingRequest()) r, exists := suite.state.GetPendingRequest(requestID) - assert.False(t, exists) - assert.Nil(t, r) + suite.Assert().False(exists) + suite.Assert().Nil(r) // Deleting again has no effect suite.state.DeletePendingRequest(requestID) - assert.False(t, suite.state.HasPendingRequest()) + suite.Assert().False(suite.state.HasPendingRequest()) } func (suite *ClientStateTestSuite) TestDeleteInvalidPendingRequest() { - t := suite.T() requestID := "1234" req := newMockRequest("somevalue") suite.state.AddPendingRequest(requestID, req) - require.True(t, suite.state.HasPendingRequest()) + suite.Require().True(suite.state.HasPendingRequest()) suite.state.DeletePendingRequest("5678") // Previously added request is still there - assert.True(t, suite.state.HasPendingRequest()) + suite.Assert().True(suite.state.HasPendingRequest()) r, exists := suite.state.GetPendingRequest(requestID) - assert.True(t, exists) - assert.NotNil(t, r) + suite.Assert().True(exists) + suite.Assert().NotNil(r) } func (suite *ClientStateTestSuite) TestClearPendingRequests() { - t := suite.T() requestID := "1234" req := newMockRequest("somevalue") suite.state.AddPendingRequest(requestID, req) - require.True(t, suite.state.HasPendingRequest()) + suite.Require().True(suite.state.HasPendingRequest()) suite.state.ClearPendingRequests() // No more requests available in the struct - assert.False(t, suite.state.HasPendingRequest()) + suite.Assert().False(suite.state.HasPendingRequest()) } type ServerStateTestSuite struct { @@ -114,7 +106,6 @@ func (suite *ServerStateTestSuite) SetupTest() { } func (suite *ServerStateTestSuite) TestAddPendingRequests() { - t := suite.T() type testClientRequest struct { clientID string requestID string @@ -128,91 +119,86 @@ func (suite *ServerStateTestSuite) TestAddPendingRequests() { for _, r := range requests { suite.state.AddPendingRequest(r.clientID, r.requestID, r.request) } - require.True(t, suite.state.HasPendingRequests()) + suite.Require().True(suite.state.HasPendingRequests()) for _, r := range requests { - assert.True(t, suite.state.HasPendingRequest(r.clientID)) + suite.Assert().True(suite.state.HasPendingRequest(r.clientID)) req, exists := suite.state.GetClientState(r.clientID).GetPendingRequest(r.requestID) - assert.True(t, exists) - assert.Equal(t, r.request, req) + suite.Assert().True(exists) + suite.Assert().Equal(r.request, req) } } func (suite *ServerStateTestSuite) TestGetInvalidPendingRequest() { - t := suite.T() requestID := "1234" clientID := "client1" suite.state.AddPendingRequest(clientID, requestID, newMockRequest("somevalue")) - require.True(t, suite.state.HasPendingRequest(clientID)) + suite.Require().True(suite.state.HasPendingRequest(clientID)) invalidRequestIDs := []string{"4321", "5678", "1230", "deadc0de"} // Nothing returned when querying for an unknown request ID for _, id := range invalidRequestIDs { r, exists := suite.state.GetClientState(clientID).GetPendingRequest(id) - assert.False(t, exists) - assert.Nil(t, r) + suite.Assert().False(exists) + suite.Assert().Nil(r) } } func (suite *ServerStateTestSuite) TestClearClientPendingRequests() { - t := suite.T() client1 := "client1" client2 := "client2" suite.state.AddPendingRequest(client1, "1234", newMockRequest("somevalue1")) suite.state.AddPendingRequest(client2, "5678", newMockRequest("somevalue2")) - require.True(t, suite.state.HasPendingRequest(client1)) + suite.Require().True(suite.state.HasPendingRequest(client1)) suite.state.ClearClientPendingRequest(client1) // Request for client1 is deleted - assert.False(t, suite.state.HasPendingRequest(client1)) + suite.Assert().False(suite.state.HasPendingRequest(client1)) r, exists := suite.state.GetClientState(client1).GetPendingRequest("1234") - assert.False(t, exists) - assert.Nil(t, r) + suite.Assert().False(exists) + suite.Assert().Nil(r) // Request for client2 is safe and sound - assert.True(t, suite.state.HasPendingRequest(client2)) + suite.Assert().True(suite.state.HasPendingRequest(client2)) } func (suite *ServerStateTestSuite) TestClearAllPendingRequests() { - t := suite.T() client1 := "client1" client2 := "client2" suite.state.AddPendingRequest(client1, "1234", newMockRequest("somevalue1")) suite.state.AddPendingRequest(client2, "5678", newMockRequest("somevalue2")) - require.True(t, suite.state.HasPendingRequests()) + suite.Require().True(suite.state.HasPendingRequests()) suite.state.ClearAllPendingRequests() - assert.False(t, suite.state.HasPendingRequests()) + suite.Assert().False(suite.state.HasPendingRequests()) // No more requests available in the struct - assert.False(t, suite.state.HasPendingRequest(client1)) - assert.False(t, suite.state.HasPendingRequest(client2)) + suite.Assert().False(suite.state.HasPendingRequest(client1)) + suite.Assert().False(suite.state.HasPendingRequest(client2)) } func (suite *ServerStateTestSuite) TestDeletePendingRequest() { - t := suite.T() client1 := "client1" client2 := "client2" suite.state.AddPendingRequest(client1, "1234", newMockRequest("somevalue1")) suite.state.AddPendingRequest(client2, "5678", newMockRequest("somevalue2")) - require.True(t, suite.state.HasPendingRequest(client1)) - require.True(t, suite.state.HasPendingRequest(client2)) + suite.Require().True(suite.state.HasPendingRequest(client1)) + suite.Require().True(suite.state.HasPendingRequest(client2)) suite.state.DeletePendingRequest(client1, "1234") // Previously added request for client1 is gone - assert.False(t, suite.state.HasPendingRequest(client1)) + suite.Assert().False(suite.state.HasPendingRequest(client1)) r, exists := suite.state.GetClientState(client1).GetPendingRequest("1234") - assert.False(t, exists) - assert.Nil(t, r) + suite.Assert().False(exists) + suite.Assert().Nil(r) // Deleting again has no effect suite.state.DeletePendingRequest(client1, "1234") - assert.False(t, suite.state.HasPendingRequest(client1)) + suite.Assert().False(suite.state.HasPendingRequest(client1)) // Previously added request for client2 is unaffected - assert.True(t, suite.state.HasPendingRequest(client2)) + suite.Assert().True(suite.state.HasPendingRequest(client2)) } func (suite *ServerStateTestSuite) TestDeleteInvalidPendingRequest() { - t := suite.T() client1 := "client1" suite.state.AddPendingRequest(client1, "1234", newMockRequest("somevalue1")) - require.True(t, suite.state.HasPendingRequest(client1)) + suite.Require().True(suite.state.HasPendingRequest(client1)) suite.state.DeletePendingRequest(client1, "5678") // Previously added request is still there - assert.True(t, suite.state.HasPendingRequest(client1)) + suite.Assert().True(suite.state.HasPendingRequest(client1)) r, exists := suite.state.GetClientState(client1).GetPendingRequest("1234") - assert.True(t, exists) - assert.NotNil(t, r) + suite.Assert().True(exists) + suite.Assert().NotNil(r) } diff --git a/ocppj/validation.go b/ocppj/validation.go new file mode 100644 index 00000000..42f254db --- /dev/null +++ b/ocppj/validation.go @@ -0,0 +1,31 @@ +package ocppj + +import ( + "sync/atomic" + + "gopkg.in/go-playground/validator.v9" +) + +// The validator, used for validating incoming/outgoing OCPP messages. +var Validate = validator.New() + +// The internal validation settings. Enabled by default. +// Safe for concurrent use. +var validationEnabled atomic.Bool + +func init() { + _ = Validate.RegisterValidation("errorCode", IsErrorCodeValid) + validationEnabled.Store(true) +} + +// Allows to enable/disable automatic validation for OCPP messages +// (this includes the field constraints defined for every request/response). +// The feature may be useful when working with OCPP implementations that don't fully comply to the specs. +// +// Validation is enabled by default. +// +// ⚠️ Use at your own risk! When disabled, outgoing and incoming OCPP messages will not be validated anymore, +// potentially leading to errors. +func SetMessageValidation(enabled bool) { + validationEnabled.Store(enabled) +} diff --git a/ocppj/validation_test.go b/ocppj/validation_test.go new file mode 100644 index 00000000..13b70e90 --- /dev/null +++ b/ocppj/validation_test.go @@ -0,0 +1,134 @@ +package ocppj_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + "github.com/xBlaz3kx/ocpp-go/ocpp" + "github.com/xBlaz3kx/ocpp-go/ocppj" +) + +type ValidationTestSuite struct { + suite.Suite + endpoint ocppj.Endpoint +} + +func (suite *ValidationTestSuite) SetupTest() { + mockProfile := ocpp.NewProfile("mock", &MockFeature{}) + suite.endpoint = ocppj.Endpoint{} + suite.endpoint.AddProfile(mockProfile) + // Ensure validation is enabled by default for each test + ocppj.SetMessageValidation(true) +} + +func (suite *ValidationTestSuite) TearDownTest() { + // Reset validation to enabled state after each test + ocppj.SetMessageValidation(true) +} + +func (suite *ValidationTestSuite) TestSetMessageValidation_DefaultEnabled() { + // Test with invalid request (empty MockValue violates "required" constraint) + invalidRequest := &MockRequest{MockValue: ""} + call, err := suite.endpoint.CreateCall(invalidRequest) + suite.Require().Error(err, "validation should fail for invalid request when enabled") + suite.Assert().Nil(call, "call should be nil when validation fails") + + // Test with valid request + validRequest := &MockRequest{MockValue: "valid"} + call, err = suite.endpoint.CreateCall(validRequest) + suite.Require().NoError(err, "validation should pass for valid request") + suite.Assert().NotNil(call, "call should not be nil when validation passes") +} + +func (suite *ValidationTestSuite) TestSetMessageValidation_DisableValidation() { + // Disable validation + ocppj.SetMessageValidation(false) + + // Test with invalid request (empty MockValue violates "required" constraint) + invalidRequest := &MockRequest{MockValue: ""} + call, err := suite.endpoint.CreateCall(invalidRequest) + suite.Require().NoError(err, "validation should be skipped when disabled") + suite.Assert().NotNil(call, "call should be created even with invalid request when validation is disabled") + + // Test with invalid request (too long MockValue violates "max=10" constraint) + invalidRequestLong := &MockRequest{MockValue: "this is way too long"} + call, err = suite.endpoint.CreateCall(invalidRequestLong) + suite.Require().NoError(err, "validation should be skipped when disabled") + suite.Assert().NotNil(call, "call should be created even with invalid request when validation is disabled") + + // Test with invalid CallResult (empty MockValue violates "required" and "min=5" constraints) + invalidConfirmation := &MockConfirmation{MockValue: ""} + callResult, err := suite.endpoint.CreateCallResult(invalidConfirmation, "test-id") + suite.Require().NoError(err, "validation should be skipped when disabled") + suite.Assert().NotNil(callResult, "callResult should be created even with invalid confirmation when validation is disabled") + + // Test with invalid CallResult (too short MockValue violates "min=5" constraint) + invalidConfirmationShort := &MockConfirmation{MockValue: "min"} + callResult, err = suite.endpoint.CreateCallResult(invalidConfirmationShort, "test-id") + suite.Require().NoError(err, "validation should be skipped when disabled") + suite.Assert().NotNil(callResult, "callResult should be created even with invalid confirmation when validation is disabled") +} + +func (suite *ValidationTestSuite) TestSetMessageValidation_EnableValidation() { + // First disable validation + ocppj.SetMessageValidation(false) + + // Verify invalid request passes when disabled + invalidRequest := &MockRequest{MockValue: ""} + call, err := suite.endpoint.CreateCall(invalidRequest) + suite.Require().NoError(err, "validation should be skipped when disabled") + suite.Assert().NotNil(call) + + // Now enable validation + ocppj.SetMessageValidation(true) + + // Same invalid request should now fail + call, err = suite.endpoint.CreateCall(invalidRequest) + suite.Require().Error(err, "validation should fail for invalid request when enabled") + suite.Assert().Nil(call, "call should be nil when validation fails") + + // Valid request should still pass + validRequest := &MockRequest{MockValue: "valid"} + call, err = suite.endpoint.CreateCall(validRequest) + suite.Require().NoError(err, "validation should pass for valid request") + suite.Assert().NotNil(call, "call should not be nil when validation passes") +} + +func (suite *ValidationTestSuite) TestSetMessageValidation_ToggleValidation() { + invalidRequest := &MockRequest{MockValue: ""} + validRequest := &MockRequest{MockValue: "valid"} + + // Test 1: Enable -> Disable -> Enable + ocppj.SetMessageValidation(true) + call, err := suite.endpoint.CreateCall(invalidRequest) + suite.Require().Error(err, "should fail when enabled") + suite.Assert().Nil(call) + + ocppj.SetMessageValidation(false) + call, err = suite.endpoint.CreateCall(invalidRequest) + suite.Require().NoError(err, "should pass when disabled") + suite.Assert().NotNil(call) + + ocppj.SetMessageValidation(true) + call, err = suite.endpoint.CreateCall(invalidRequest) + suite.Require().Error(err, "should fail when enabled again") + suite.Assert().Nil(call) + + // Test 2: Valid request should always pass regardless of validation setting + ocppj.SetMessageValidation(true) + call, err = suite.endpoint.CreateCall(validRequest) + suite.Require().NoError(err, "valid request should pass when enabled") + suite.Assert().NotNil(call) + + ocppj.SetMessageValidation(false) + call, err = suite.endpoint.CreateCall(validRequest) + suite.Require().NoError(err, "valid request should pass when disabled") + suite.Assert().NotNil(call) +} + +func TestValidationSuite(t *testing.T) { + if !testing.Short() { + t.Skip("") + } + suite.Run(t, new(ValidationTestSuite)) +} diff --git a/ws/client.go b/ws/client.go index 1d224c80..df1a2bdd 100644 --- a/ws/client.go +++ b/ws/client.go @@ -12,6 +12,7 @@ import ( "time" "github.com/gorilla/websocket" + "github.com/xBlaz3kx/ocpp-go/logging" ) // ---------------------- CLIENT ---------------------- @@ -27,7 +28,7 @@ import ( // // certPool, err := x509.SystemCertPool() // if err != nil { -// log.Fatal(err) +// c.logger.Fatal(err) // } // // You may add more trusted certificates to the pool before creating the TLS Config // client := NewClient(&tls.Config{ @@ -124,6 +125,7 @@ type Client interface { // // Use the NewClient function to create a new client. type client struct { + logger logging.Logger webSocket *webSocket url url.URL messageHandler func(data []byte) error @@ -151,6 +153,25 @@ func WithClientTLSConfig(tlsConfig *tls.Config) ClientOpt { } } +func WithClientCompression(enable bool) ClientOpt { + return func(c *client) { + c.dialOptions = append(c.dialOptions, func(dialer *websocket.Dialer) { + dialer.EnableCompression = enable + }) + } +} + +// WithClientLogger sets the logger for the client. +// If not set, a VoidLogger will be used. +func WithClientLogger(logger logging.Logger) ClientOpt { + return func(c *client) { + if logger == nil { + logger = &logging.VoidLogger{} + } + c.logger = logger + } +} + // NewClient creates a new websocket client. // // If the optional tlsConfig is not nil, and the server supports secure communication, @@ -179,6 +200,7 @@ func WithClientTLSConfig(tlsConfig *tls.Config) ClientOpt { // InsecureSkipVerify: true func NewClient(opts ...ClientOpt) Client { c := &client{ + logger: &logging.VoidLogger{}, dialOptions: []func(*websocket.Dialer){}, timeoutConfig: NewClientTimeoutConfig(), reconnectC: make(chan struct{}, 1), @@ -245,7 +267,7 @@ func (c *client) getReadTimeout() time.Time { } func (c *client) handleReconnection() { - log.Info("started automatic reconnection handler") + c.logger.Info("started automatic reconnection handler") delay := c.timeoutConfig.RetryBackOffWaitMinimum + time.Duration(rand.Intn(c.timeoutConfig.RetryBackOffRandomRange+1))*time.Second reconnectionAttempts := 1 for { @@ -253,15 +275,15 @@ func (c *client) handleReconnection() { select { case <-time.After(delay): case <-c.reconnectC: - log.Info("automatic reconnection aborted") + c.logger.Info("automatic reconnection aborted") return } - log.Info("reconnecting... attempt", reconnectionAttempts) + c.logger.Info("reconnecting... attempt", reconnectionAttempts) err := c.Start(c.url.String()) if err == nil { // Re-connection was successful - log.Info("reconnected successfully to server") + c.logger.Info("reconnected successfully to server") if c.onReconnected != nil { c.onReconnected() } @@ -289,14 +311,14 @@ func (c *client) Write(data []byte) error { if !c.IsConnected() { return fmt.Errorf("client is currently not connected, cannot send data") } - log.Debugf("queuing data for server") + c.logger.Debugf("queuing data for server") return c.webSocket.Write(data) } func (c *client) StartWithRetries(urlStr string) { err := c.Start(urlStr) if err != nil { - log.Info("Connection error:", err) + c.logger.Info("Connection error:", err) c.handleReconnection() } } @@ -321,7 +343,7 @@ func (c *client) Start(urlStr string) error { option(&dialer) } // Connect - log.Info("connecting to server") + c.logger.Info("connecting to server") ws, resp, err := dialer.Dial(urlStr, c.header) if err != nil { if resp != nil { @@ -341,7 +363,7 @@ func (c *client) Start(urlStr string) error { id := path.Base(u.Path) // Create web socket, state is automatically set to connected - c.webSocket = newWebSocket( + c.webSocket, err = newWebSocket( id, ws, resp.TLS, @@ -350,6 +372,7 @@ func (c *client) Start(urlStr string) error { 0, c.timeoutConfig.PingPeriod, c.timeoutConfig.PongWait, + c.logger, ), c.handleMessage, c.handleDisconnect, @@ -357,14 +380,18 @@ func (c *client) Start(urlStr string) error { c.error(err) }, ) - log.Infof("connected to server as %s", id) + if err != nil { + return fmt.Errorf("failed to create websocket channel: %w", err) + } + + c.logger.Infof("connected to server as %s", id) // Start reader and write routine c.webSocket.run() return nil } func (c *client) Stop() { - log.Infof("closing connection to server") + c.logger.Infof("closing connection to server") if c.IsConnected() { // Attempt to gracefully shut down the connection err := c.webSocket.Close(websocket.CloseError{Code: websocket.CloseNormalClosure, Text: ""}) @@ -422,7 +449,7 @@ func (c *client) handleDisconnect(_ Channel, err error) { } func (c *client) error(err error) { - log.Error(err) + c.logger.Error(err) if c.errC != nil { c.errC <- err } diff --git a/ws/metrics.go b/ws/metrics.go new file mode 100644 index 00000000..c8bfa7e5 --- /dev/null +++ b/ws/metrics.go @@ -0,0 +1,100 @@ +package ws + +import ( + "context" + "fmt" + "sync/atomic" + "time" + + "github.com/pkg/errors" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" +) + +const ( + chargePointsConnectedMetric = "websocket_charge_points_connected" + messageRateMetric = "websocket_message_rate" + pingPongDurationMetric = "websocket_ping_pong_duration" + attributeChargePointId = "charge_point_id" + attributeDirection = "direction" +) + +const ( + directionInbound = "inbound" + directionOutbound = "outbound" +) + +type serverMetrics struct { + connectedChargePoints atomic.Int64 + + chargePointsConnectedMetric metric.Int64ObservableGauge + pingPongDurationMetric metric.Float64Histogram + messageRate metric.Int64Histogram +} + +func newServerMetrics(meterProvider metric.MeterProvider) (*serverMetrics, error) { + meter := meterProvider.Meter("websocket") + m := &serverMetrics{} + + chargePointsConnected, err := meter.Int64ObservableGauge( + chargePointsConnectedMetric, + metric.WithDescription("Number of currently connected charge points"), + metric.WithInt64Callback(func(ctx context.Context, io metric.Int64Observer) error { + io.Observe(m.connectedChargePoints.Load()) + return nil + }), + ) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("failed to create %s metric", chargePointsConnectedMetric)) + } + + messageRate, err := meter.Int64Histogram( + messageRateMetric, + metric.WithDescription("Message rate"), + ) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("failed to create %s metric", messageRateMetric)) + } + + m.pingPongDurationMetric, err = meter.Float64Histogram( + pingPongDurationMetric, + metric.WithDescription("Duration of ping-pong messages"), + metric.WithUnit("s"), + ) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("failed to create %s metric", pingPongDurationMetric)) + } + + m.chargePointsConnectedMetric = chargePointsConnected + m.messageRate = messageRate + + return m, nil +} + +func (m *serverMetrics) IncrementChargePoints() { + m.connectedChargePoints.Add(1) +} + +func (m *serverMetrics) DecrementChargePoints() { + // Only positive values are allowed + if m.connectedChargePoints.Load() == 0 { + return + } + + m.connectedChargePoints.Add(1) +} + +func (m *serverMetrics) RecordMessageRate(ctx context.Context, chargePointId string, direction string) { + attributes := metric.WithAttributes( + attribute.String(attributeChargePointId, chargePointId), + attribute.String(attributeDirection, direction), + ) + m.messageRate.Record(ctx, 1, attributes) +} + +func (m *serverMetrics) RecordPingPongDuration(ctx context.Context, duration time.Duration, chargePointId string) { + attributes := metric.WithAttributes( + attribute.String(attributeChargePointId, chargePointId), + ) + m.pingPongDurationMetric.Record(ctx, duration.Seconds(), attributes) +} diff --git a/ws/mocks/mock_Channel.go b/ws/mocks/mock_Channel.go index cf5d228e..ec7e5e11 100644 --- a/ws/mocks/mock_Channel.go +++ b/ws/mocks/mock_Channel.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks diff --git a/ws/mocks/mock_CheckClientHandler.go b/ws/mocks/mock_CheckClientHandler.go index 56e1d614..5bfaecab 100644 --- a/ws/mocks/mock_CheckClientHandler.go +++ b/ws/mocks/mock_CheckClientHandler.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks diff --git a/ws/mocks/mock_Client.go b/ws/mocks/mock_Client.go index 3d0dc510..53ba8dc3 100644 --- a/ws/mocks/mock_Client.go +++ b/ws/mocks/mock_Client.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ws "github.com/lorenzodonini/ocpp-go/ws" mock "github.com/stretchr/testify/mock" + ws "github.com/xBlaz3kx/ocpp-go/ws" ) // MockClient is an autogenerated mock type for the Client type diff --git a/ws/mocks/mock_ClientOpt.go b/ws/mocks/mock_ClientOpt.go index 2272797c..0de83594 100644 --- a/ws/mocks/mock_ClientOpt.go +++ b/ws/mocks/mock_ClientOpt.go @@ -1,8 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks -import mock "github.com/stretchr/testify/mock" +import ( + mock "github.com/stretchr/testify/mock" +) // MockClientOpt is an autogenerated mock type for the ClientOpt type type MockClientOpt struct { @@ -18,7 +20,8 @@ func (_m *MockClientOpt) EXPECT() *MockClientOpt_Expecter { } // Execute provides a mock function with given fields: c -func (_m *MockClientOpt) Execute(c *ws.client) { +// Note: Using interface{} since client is unexported +func (_m *MockClientOpt) Execute(c interface{}) { _m.Called(c) } @@ -33,9 +36,9 @@ func (_e *MockClientOpt_Expecter) Execute(c interface{}) *MockClientOpt_Execute_ return &MockClientOpt_Execute_Call{Call: _e.mock.On("Execute", c)} } -func (_c *MockClientOpt_Execute_Call) Run(run func(c *ws.client)) *MockClientOpt_Execute_Call { +func (_c *MockClientOpt_Execute_Call) Run(run func(c interface{})) *MockClientOpt_Execute_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*ws.client)) + run(args[0]) }) return _c } @@ -45,7 +48,7 @@ func (_c *MockClientOpt_Execute_Call) Return() *MockClientOpt_Execute_Call { return _c } -func (_c *MockClientOpt_Execute_Call) RunAndReturn(run func(*ws.client)) *MockClientOpt_Execute_Call { +func (_c *MockClientOpt_Execute_Call) RunAndReturn(run func(interface{})) *MockClientOpt_Execute_Call { _c.Run(run) return _c } diff --git a/ws/mocks/mock_ConnectedHandler.go b/ws/mocks/mock_ConnectedHandler.go index 51c89a66..ba374565 100644 --- a/ws/mocks/mock_ConnectedHandler.go +++ b/ws/mocks/mock_ConnectedHandler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ws "github.com/lorenzodonini/ocpp-go/ws" mock "github.com/stretchr/testify/mock" + ws "github.com/xBlaz3kx/ocpp-go/ws" ) // MockConnectedHandler is an autogenerated mock type for the ConnectedHandler type diff --git a/ws/mocks/mock_DisconnectedHandler.go b/ws/mocks/mock_DisconnectedHandler.go index a2026741..c3e88efe 100644 --- a/ws/mocks/mock_DisconnectedHandler.go +++ b/ws/mocks/mock_DisconnectedHandler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ws "github.com/lorenzodonini/ocpp-go/ws" mock "github.com/stretchr/testify/mock" + ws "github.com/xBlaz3kx/ocpp-go/ws" ) // MockDisconnectedHandler is an autogenerated mock type for the DisconnectedHandler type diff --git a/ws/mocks/mock_ErrorHandler.go b/ws/mocks/mock_ErrorHandler.go index 2f289861..6621ddab 100644 --- a/ws/mocks/mock_ErrorHandler.go +++ b/ws/mocks/mock_ErrorHandler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ws "github.com/lorenzodonini/ocpp-go/ws" mock "github.com/stretchr/testify/mock" + ws "github.com/xBlaz3kx/ocpp-go/ws" ) // MockErrorHandler is an autogenerated mock type for the ErrorHandler type diff --git a/ws/mocks/mock_MessageHandler.go b/ws/mocks/mock_MessageHandler.go index 7f1000c5..3902a489 100644 --- a/ws/mocks/mock_MessageHandler.go +++ b/ws/mocks/mock_MessageHandler.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks import ( - ws "github.com/lorenzodonini/ocpp-go/ws" mock "github.com/stretchr/testify/mock" + ws "github.com/xBlaz3kx/ocpp-go/ws" ) // MockMessageHandler is an autogenerated mock type for the MessageHandler type diff --git a/ws/mocks/mock_Server.go b/ws/mocks/mock_Server.go index f8ffe9aa..3751c64a 100644 --- a/ws/mocks/mock_Server.go +++ b/ws/mocks/mock_Server.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks @@ -10,7 +10,7 @@ import ( websocket "github.com/gorilla/websocket" - ws "github.com/lorenzodonini/ocpp-go/ws" + ws "github.com/xBlaz3kx/ocpp-go/ws" ) // MockServer is an autogenerated mock type for the Server type diff --git a/ws/mocks/mock_ServerOpt.go b/ws/mocks/mock_ServerOpt.go index 8c1ce686..dae4ed4b 100644 --- a/ws/mocks/mock_ServerOpt.go +++ b/ws/mocks/mock_ServerOpt.go @@ -1,8 +1,10 @@ -// Code generated by mockery v2.51.0. DO NOT EDIT. +// Code generated by mockery v2.53.5. DO NOT EDIT. package mocks -import mock "github.com/stretchr/testify/mock" +import ( + mock "github.com/stretchr/testify/mock" +) // MockServerOpt is an autogenerated mock type for the ServerOpt type type MockServerOpt struct { @@ -18,7 +20,8 @@ func (_m *MockServerOpt) EXPECT() *MockServerOpt_Expecter { } // Execute provides a mock function with given fields: s -func (_m *MockServerOpt) Execute(s *ws.server) { +// Note: Using interface{} since server is unexported +func (_m *MockServerOpt) Execute(s interface{}) { _m.Called(s) } @@ -33,9 +36,9 @@ func (_e *MockServerOpt_Expecter) Execute(s interface{}) *MockServerOpt_Execute_ return &MockServerOpt_Execute_Call{Call: _e.mock.On("Execute", s)} } -func (_c *MockServerOpt_Execute_Call) Run(run func(s *ws.server)) *MockServerOpt_Execute_Call { +func (_c *MockServerOpt_Execute_Call) Run(run func(s interface{})) *MockServerOpt_Execute_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*ws.server)) + run(args[0]) }) return _c } @@ -45,7 +48,7 @@ func (_c *MockServerOpt_Execute_Call) Return() *MockServerOpt_Execute_Call { return _c } -func (_c *MockServerOpt_Execute_Call) RunAndReturn(run func(*ws.server)) *MockServerOpt_Execute_Call { +func (_c *MockServerOpt_Execute_Call) RunAndReturn(run func(interface{})) *MockServerOpt_Execute_Call { _c.Run(run) return _c } diff --git a/ws/mocks/mock_WsClient.go b/ws/mocks/mock_WsClient.go index 40a32fb9..479177fb 100644 --- a/ws/mocks/mock_WsClient.go +++ b/ws/mocks/mock_WsClient.go @@ -3,8 +3,8 @@ package mocks import ( - ws "github.com/lorenzodonini/ocpp-go/ws" mock "github.com/stretchr/testify/mock" + ws "github.com/xBlaz3kx/ocpp-go/ws" ) // MockWsClient is an autogenerated mock type for the WsClient type diff --git a/ws/mocks/mock_WsServer.go b/ws/mocks/mock_WsServer.go index c382b211..6fffef87 100644 --- a/ws/mocks/mock_WsServer.go +++ b/ws/mocks/mock_WsServer.go @@ -10,7 +10,7 @@ import ( websocket "github.com/gorilla/websocket" - ws "github.com/lorenzodonini/ocpp-go/ws" + ws "github.com/xBlaz3kx/ocpp-go/ws" ) // MockWsServer is an autogenerated mock type for the WsServer type @@ -107,19 +107,19 @@ func (_c *MockWsServer_Addr_Call) RunAndReturn(run func() *net.TCPAddr) *MockWsS } // Connections provides a mock function with given fields: websocketId -func (_m *MockWsServer) Connections(websocketId string) *ws.WebSocket { +func (_m *MockWsServer) Connections(websocketId string) ws.Channel { ret := _m.Called(websocketId) if len(ret) == 0 { panic("no return value specified for Connections") } - var r0 *ws.WebSocket - if rf, ok := ret.Get(0).(func(string) *ws.WebSocket); ok { + var r0 ws.Channel + if rf, ok := ret.Get(0).(func(string) ws.Channel); ok { r0 = rf(websocketId) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*ws.WebSocket) + r0 = ret.Get(0).(ws.Channel) } } @@ -144,12 +144,12 @@ func (_c *MockWsServer_Connections_Call) Run(run func(websocketId string)) *Mock return _c } -func (_c *MockWsServer_Connections_Call) Return(_a0 *ws.WebSocket) *MockWsServer_Connections_Call { +func (_c *MockWsServer_Connections_Call) Return(_a0 ws.Channel) *MockWsServer_Connections_Call { _c.Call.Return(_a0) return _c } -func (_c *MockWsServer_Connections_Call) RunAndReturn(run func(string) *ws.WebSocket) *MockWsServer_Connections_Call { +func (_c *MockWsServer_Connections_Call) RunAndReturn(run func(string) ws.Channel) *MockWsServer_Connections_Call { _c.Call.Return(run) return _c } diff --git a/ws/server.go b/ws/server.go index 7aaf03b2..c0aac6e0 100644 --- a/ws/server.go +++ b/ws/server.go @@ -3,7 +3,6 @@ package ws import ( "context" "crypto/tls" - "errors" "fmt" "net" "net/http" @@ -13,6 +12,10 @@ import ( "github.com/gorilla/mux" "github.com/gorilla/websocket" + "github.com/pkg/errors" + "github.com/xBlaz3kx/ocpp-go/logging" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/metric" ) // ---------------------- SERVER ---------------------- @@ -130,6 +133,7 @@ type Server interface { // // Use the NewServer function to create a new server. type server struct { + logger logging.Logger connections map[string]*webSocket httpServer *http.Server messageHandler func(ws Channel, data []byte) error @@ -140,12 +144,15 @@ type server struct { basicAuthHandler func(username string, password string) bool tlsCertificatePath string tlsCertificateKey string - timeoutConfig ServerTimeoutConfig - upgrader websocket.Upgrader - errC chan error - connMutex sync.RWMutex - addr *net.TCPAddr - httpHandler *mux.Router + // enableCompression is used to enable or disable compression for the websocket connections. + enableCompression bool + timeoutConfig ServerTimeoutConfig + upgrader websocket.Upgrader + errC chan error + connMutex sync.RWMutex + addr *net.TCPAddr + httpHandler *mux.Router + metrics *serverMetrics } // ServerOpt is a function that can be used to set options on a server during creation. @@ -163,6 +170,38 @@ func WithServerTLSConfig(certificatePath string, certificateKey string, tlsConfi } } +// WithCompression enables or disables compression for the websocket connections. +// By default, compression is disabled. +func WithCompression(enabled bool) ServerOpt { + return func(s *server) { + s.enableCompression = enabled + } +} + +// WithServerMeterProvider sets the meter provider for server metrics. +// It will create metrics with the given provider and attach them to the server. +func WithServerMeterProvider(meterProvider metric.MeterProvider) ServerOpt { + return func(s *server) { + m, err := newServerMetrics(meterProvider) + if err != nil { + return + } + + s.metrics = m + } +} + +// WithServerLogger sets the logger for the server. +// If not set, a VoidLogger will be used. +func WithServerLogger(logger logging.Logger) ServerOpt { + return func(s *server) { + if logger == nil { + logger = &logging.VoidLogger{} + } + s.logger = logger + } +} + // NewServer Creates a new websocket server. // // Additional options may be added using the AddOption function. @@ -181,8 +220,13 @@ func WithServerTLSConfig(certificatePath string, certificateKey string, tlsConfi // // When TLS is correctly configured, the server will automatically use it for all created websocket channels. func NewServer(opts ...ServerOpt) Server { + // Note: If metrics are not configured, a noop meter provider is used and no metrics are exported. + meterProvider := otel.GetMeterProvider() + serverMetrics, err := newServerMetrics(meterProvider) + router := mux.NewRouter() s := &server{ + logger: &logging.VoidLogger{}, httpServer: &http.Server{}, timeoutConfig: NewServerTimeoutConfig(), upgrader: websocket.Upgrader{Subprotocols: []string{}}, @@ -191,10 +235,18 @@ func NewServer(opts ...ServerOpt) Server { url := r.URL return path.Base(url.Path), nil }, + metrics: serverMetrics, } for _, o := range opts { o(s) } + + if err != nil { + // todo improve error handling + s.logger.Error(errors.Wrap(err, "Error creating websocket server metrics")) + } + + s.upgrader.EnableCompression = s.enableCompression return s } @@ -241,7 +293,7 @@ func (s *server) SetCheckOriginHandler(handler func(r *http.Request) bool) { } func (s *server) error(err error) { - log.Error(err) + s.logger.Error(err) if s.errC != nil { s.errC <- err } @@ -284,12 +336,11 @@ func (s *server) Start(port int, listenPath string) { s.error(fmt.Errorf("failed to listen: %w", err)) return } + defer ln.Close() s.addr = ln.Addr().(*net.TCPAddr) - defer ln.Close() - - log.Infof("listening on tcp network %v", addr) + s.logger.Infof("listening on tcp network %v", addr) s.httpServer.RegisterOnShutdown(s.stopConnections) if s.tlsCertificatePath != "" && s.tlsCertificateKey != "" { err = s.httpServer.ServeTLS(ln, s.tlsCertificatePath, s.tlsCertificateKey) @@ -303,8 +354,8 @@ func (s *server) Start(port int, listenPath string) { } func (s *server) Stop() { - log.Info("stopping websocket server") - err := s.httpServer.Shutdown(context.TODO()) + s.logger.Info("stopping websocket server") + err := s.httpServer.Shutdown(context.Background()) if err != nil { s.error(fmt.Errorf("shutdown failed: %w", err)) } @@ -316,15 +367,21 @@ func (s *server) Stop() { } func (s *server) StopConnection(id string, closeError websocket.CloseError) error { - s.connMutex.RLock() + s.connMutex.Lock() + defer s.connMutex.Unlock() w, ok := s.connections[id] - s.connMutex.RUnlock() - if !ok { return fmt.Errorf("couldn't stop websocket connection. No connection with id %s is open", id) } - log.Debugf("sending stop signal for websocket %s", w.ID()) - return w.Close(closeError) + + s.logger.Debugf("sending stop signal for websocket %s", w.ID()) + + err := w.Close(closeError) + if err == nil { + delete(s.connections, id) + } + + return err } func (s *server) GetChannel(websocketId string) (Channel, bool) { @@ -335,11 +392,18 @@ func (s *server) GetChannel(websocketId string) (Channel, bool) { } func (s *server) stopConnections() { - s.connMutex.RLock() - defer s.connMutex.RUnlock() + s.connMutex.Lock() + defer s.connMutex.Lock() + for _, conn := range s.connections { - _ = conn.Close(websocket.CloseError{Code: websocket.CloseNormalClosure, Text: ""}) + err := conn.Close(websocket.CloseError{Code: websocket.CloseNormalClosure, Text: ""}) + if err != nil { + s.logger.Error("Unable to close connection for ", conn.id, ": ", err.Error()) + } } + + // Reset the connections + s.connections = make(map[string]*webSocket) } func (s *server) Write(webSocketId string, data []byte) error { @@ -349,7 +413,10 @@ func (s *server) Write(webSocketId string, data []byte) error { if !ok { return fmt.Errorf("couldn't write to websocket. No socket with id %v is open", webSocketId) } - log.Debugf("queuing data for websocket %s", webSocketId) + s.logger.Debugf("queuing data for websocket %s", webSocketId) + + s.metrics.RecordMessageRate(context.Background(), webSocketId, directionOutbound) + return w.Write(data) } @@ -361,7 +428,7 @@ func (s *server) wsHandler(w http.ResponseWriter, r *http.Request) { http.Error(w, "NotFound", http.StatusNotFound) return } - log.Debugf("handling new connection for %s from %s", id, r.RemoteAddr) + s.logger.Debugf("handling new connection for %s from %s", id, r.RemoteAddr) // Negotiate sub-protocol clientSubProtocols := websocket.Subprotocols(r) negotiatedSubProtocol := "" @@ -372,7 +439,7 @@ out: negotiatedSubProtocol = requestedProto break } - // Check if requested suprotocol is supported by server + // Check if requested subprotocol is supported by server for _, supportedProto := range s.upgrader.Subprotocols { if requestedProto == supportedProto { negotiatedSubProtocol = requestedProto @@ -413,7 +480,7 @@ out: return } - log.Debugf("upgraded websocket connection for %s from %s", id, conn.RemoteAddr().String()) + s.logger.Debugf("upgraded websocket connection for %s from %s", id, conn.RemoteAddr().String()) // If unsupported sub-protocol, terminate the connection immediately if negotiatedSubProtocol == "" { s.error(fmt.Errorf("unsupported subprotocols %v for new client %v (%v)", clientSubProtocols, id, r.RemoteAddr)) @@ -436,7 +503,7 @@ out: return } // Create web socket for client, state is automatically set to connected - ws := newWebSocket( + ws, err := newWebSocket( id, conn, r.TLS, @@ -444,16 +511,27 @@ out: s.timeoutConfig.WriteWait, s.timeoutConfig.PingWait, s.timeoutConfig.PingPeriod, - s.timeoutConfig.PongWait), + s.timeoutConfig.PongWait, + s.logger), s.handleMessage, s.handleDisconnect, func(_ Channel, err error) { s.error(err) }, ) + if err != nil { + s.connMutex.Unlock() + s.error(fmt.Errorf("failed to create websocket for client %s: %w", id, err)) + http.Error(w, "Internal Server Error", http.StatusInternalServerError) + return + } + // Add new client s.connections[ws.id] = ws s.connMutex.Unlock() + + s.metrics.IncrementChargePoints() + // Start reader and write routine ws.run() if s.newClientHandler != nil { @@ -465,6 +543,7 @@ out: // --------- Internal callbacks webSocket -> server --------- func (s *server) handleMessage(w Channel, data []byte) error { if s.messageHandler != nil { + s.metrics.RecordMessageRate(context.Background(), w.ID(), directionInbound) return s.messageHandler(w, data) } return fmt.Errorf("no message handler set") @@ -475,8 +554,10 @@ func (s *server) handleDisconnect(w Channel, _ error) { s.connMutex.Lock() delete(s.connections, w.ID()) s.connMutex.Unlock() - log.Infof("closed connection to %s", w.ID()) + s.logger.Infof("closed connection to %s", w.ID()) if s.disconnectedHandler != nil { s.disconnectedHandler(w) } + + s.metrics.DecrementChargePoints() } diff --git a/ws/websocket.go b/ws/websocket.go index 0ec621ba..8215173f 100644 --- a/ws/websocket.go +++ b/ws/websocket.go @@ -12,7 +12,7 @@ import ( "time" "github.com/gorilla/websocket" - "github.com/lorenzodonini/ocpp-go/logging" + "github.com/xBlaz3kx/ocpp-go/logging" ) const ( @@ -41,20 +41,6 @@ const ( defaultRetryBackOffWaitMinimum = 10 * time.Second ) -// The internal verbose logger -var log logging.Logger - -// Sets a custom Logger implementation, allowing the package to log events. -// By default, a VoidLogger is used, so no logs will be sent to any output. -// -// The function panics, if a nil logger is passed. -func SetLogger(logger logging.Logger) { - if logger == nil { - panic("cannot set a nil logger") - } - log = logger -} - // ServerTimeoutConfig contains optional configuration parameters for a websocket server. // Setting the parameter allows to define custom timeout intervals for websocket network operations. // @@ -190,11 +176,13 @@ type PingConfig struct { // If sendPing is set, the websocket will be configured to send out periodic pings. // // No custom configuration functions are run. Overrides need to be applied externally. +// If logger is nil, a VoidLogger will be used. func NewDefaultWebSocketConfig( writeWait time.Duration, readWait time.Duration, pingPeriod time.Duration, - pongWait time.Duration) WebSocketConfig { + pongWait time.Duration, + logger logging.Logger) WebSocketConfig { var pingCfg *PingConfig if pingPeriod > 0 { pingCfg = &PingConfig{ @@ -202,11 +190,14 @@ func NewDefaultWebSocketConfig( PongWait: pongWait, } } + if logger == nil { + logger = &logging.VoidLogger{} + } return WebSocketConfig{ WriteWait: writeWait, ReadWait: readWait, PingConfig: pingCfg, - Logger: log, + Logger: logger, } } @@ -240,9 +231,9 @@ type webSocket struct { onMessage MessageHandler } -func newWebSocket(id string, conn *websocket.Conn, tlsState *tls.ConnectionState, cfg WebSocketConfig, onMessage MessageHandler, onClosed DisconnectedHandler, onError ErrorHandler) *webSocket { +func newWebSocket(id string, conn *websocket.Conn, tlsState *tls.ConnectionState, cfg WebSocketConfig, onMessage MessageHandler, onClosed DisconnectedHandler, onError ErrorHandler) (*webSocket, error) { if conn == nil { - panic("cannot create websocket with nil connection") + return nil, fmt.Errorf("cannot create websocket %s with nil connection", id) } w := &webSocket{ id: id, @@ -258,7 +249,7 @@ func newWebSocket(id string, conn *websocket.Conn, tlsState *tls.ConnectionState onMessage: onMessage, } w.updateConfig(cfg) - return w + return w, nil } // Retrieves the unique Identifier of the websocket (typically, the URL suffix). @@ -314,12 +305,12 @@ func (w *webSocket) updateConfig(cfg WebSocketConfig) { w.mutex.Lock() defer w.mutex.Unlock() w.cfg = cfg - // Update logger + + w.log = &logging.VoidLogger{} if cfg.Logger != nil { w.log = cfg.Logger - } else { - w.log = log } + // Update ping pong logic w.initPingPong() } @@ -340,17 +331,15 @@ func (w *webSocket) getReadTimeout() time.Time { func (w *webSocket) initPingPong() { conn := w.connection + if w.cfg.ReadWait > 0 { // Expect pings, reply with pongs conn.SetPingHandler(w.onPing) - } else { - conn.SetPingHandler(nil) } + if w.cfg.PingConfig != nil { // Optionally send pings, expect pongs conn.SetPongHandler(w.onPong) - } else { - conn.SetPongHandler(nil) } } @@ -375,7 +364,7 @@ func (w *webSocket) cleanup(err error) { w.mutex.Lock() // Properly close the connection if e := w.connection.Close(); e != nil { - log.Errorf("failed to close connection for %s: %v", w.id, e) + w.log.Errorf("failed to close connection for %s: %v", w.id, e) } w.connection = nil close(w.outQueue) @@ -449,27 +438,32 @@ func (w *webSocket) writePump() { for { select { case <-ticker.T(): + w.mutex.Lock() // Send periodic ping _ = conn.SetWriteDeadline(time.Now().Add(w.cfg.WriteWait)) err := conn.WriteMessage(websocket.PingMessage, []byte{}) + w.mutex.Unlock() if err != nil { w.onError(w, fmt.Errorf("failed to send ping message for %s: %w", w.id, err)) // Invoking cleanup, as socket was forcefully closed closure(err) return } - log.Debugf("ping sent for %s", w.id) + w.log.Debugf("ping sent for %s", w.id) case ping := <-w.pingC: // Reply with pong message + w.mutex.Lock() _ = conn.SetWriteDeadline(time.Now().Add(w.cfg.WriteWait)) err := conn.WriteMessage(websocket.PongMessage, ping) + w.mutex.Unlock() + if err != nil { w.onError(w, fmt.Errorf("failed to send pong message %s: %w", w.id, err)) // Invoking cleanup, as socket was forcefully closed closure(err) return } - log.Debugf("pong sent for %s: %s", w.id, string(ping)) + w.log.Debugf("pong sent for %s: %s", w.id, string(ping)) case msg, ok := <-w.outQueue: // New data needs to be written out (also invoked for pong messages) if !ok { @@ -479,23 +473,28 @@ func (w *webSocket) writePump() { return } // Send data + w.mutex.Lock() _ = conn.SetWriteDeadline(time.Now().Add(w.cfg.WriteWait)) err := conn.WriteMessage(msg.typ, msg.data) + w.mutex.Unlock() if err != nil { w.onError(w, fmt.Errorf("write failed for %s: %w", w.id, err)) // Invoking cleanup, as socket was forcefully closed closure(err) return } - log.Debugf("written %d bytes to %s", len(msg.data), w.id) + w.log.Debugf("written %d bytes to %s", len(msg.data), w.id) case closeErr := <-w.closeC: // webSocket is being gracefully closed by user command w.log.Debugf("closing connection for %s: %d - %s", w.id, closeErr.Code, closeErr.Text) + + w.mutex.Lock() // Send explicit close message err := conn.WriteControl( websocket.CloseMessage, websocket.FormatCloseMessage(closeErr.Code, closeErr.Text), time.Now().Add(w.cfg.WriteWait)) + w.mutex.Unlock() if err != nil { // At this point the connection is considered to be forcefully closed, // but we still continue with the intended flow. @@ -510,7 +509,7 @@ func (w *webSocket) writePump() { closed = fmt.Errorf("websocket read channel closed abruptly") } // webSocket is being forcefully closed, triggered by readPump encountering a failed read. - log.Debugf("handling forced close signal for %s, caused by: %v", w.id, closed.Error()) + w.log.Debugf("handling forced close signal for %s, caused by: %v", w.id, closed.Error()) // Connection was forcefully closed, invoke cleanup closure(closed) return @@ -530,7 +529,3 @@ type HttpConnectionError struct { func (e HttpConnectionError) Error() string { return fmt.Sprintf("%v, http status: %v", e.Message, e.HttpStatus) } - -func init() { - log = &logging.VoidLogger{} -} diff --git a/ws/websocket_test.go b/ws/websocket_test.go index 7cde5c1c..12ff1b20 100644 --- a/ws/websocket_test.go +++ b/ws/websocket_test.go @@ -355,6 +355,31 @@ func (s *WebSocketSuite) TestWebsocketChargePointIdResolverFailure() { s.Equal("websocket: bad handshake", httpErr.Message) } +func (s *WebSocketSuite) TestWebsocketEnableCompression() { + s.server = newWebsocketServer(s.T(), func(data []byte) ([]byte, error) { + s.Fail("no message should be received from client!") + return nil, nil + }) + s.server.upgrader.EnableCompression = true + go s.server.Start(serverPort, serverPath) + time.Sleep(500 * time.Millisecond) + + // Test message + s.client = newWebsocketClient(s.T(), func(data []byte) ([]byte, error) { + s.Fail("no message should be received from server!") + return nil, nil + }) + + host := fmt.Sprintf("localhost:%v", serverPort) + u := url.URL{Scheme: "ws", Host: host, Path: testPath} + s.client.AddOption(func(dialer *websocket.Dialer) { + dialer.EnableCompression = true + }) + // Attempt to connect, expecting compression to be enabled + err := s.client.Start(u.String()) + s.NoError(err) +} + func (s *WebSocketSuite) TestWebsocketBootRetries() { verifyConnection := func(client *client, connected bool) { maxAttempts := 20