Skip to content

Commit

Permalink
Automated tests for logzio-k8s-telemetry and logzio-logs-colector
Browse files Browse the repository at this point in the history
… charts (#496)

* Add files to branch

* Edit container metrics query

* Add api environment variables

* Use `secrets` in workflows
  • Loading branch information
yotamloe authored Jun 18, 2024
1 parent 4f5980f commit ab68b71
Show file tree
Hide file tree
Showing 10 changed files with 673 additions and 0 deletions.
76 changes: 76 additions & 0 deletions .github/workflows/logzio-logs-collector-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Test Logzio Logs Collector Helm Chart on Kind Kubernetes Environment

on:
pull_request:
branches:
- main
paths:
- 'charts/logzio-logs-collector/**'
jobs:
test-helm-chart:
name: Test Helm Chart on Kind
runs-on: ubuntu-latest
steps:
- name: Generate random id
id: random_id
run: echo "::set-output name=rand::$(echo $RANDOM)"

- name: Set ENV_ID
run: echo "ENV_ID=logs-test-run-${{ steps.random_id.outputs.rand }}" >> $GITHUB_ENV

- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.20'

- name: Set up Helm
uses: azure/[email protected]

- name: Set up kubectl
uses: azure/setup-kubectl@v3

- name: Install Kind
run: |
curl -Lo ./kind "https://kind.sigs.k8s.io/dl/v0.11.1/kind-Linux-amd64"
chmod +x ./kind
mv ./kind /usr/local/bin/kind
- name: Create Kind cluster
run: |
kind create cluster --name kind-${{ github.run_id }}
kubectl cluster-info
- name: Deploy Helm Chart
run: |
cd charts/logzio-logs-collector
helm upgrade --install \
--set secrets.env_id=${{ env.ENV_ID }} \
--set secrets.logzioLogsToken=${{ secrets.LOGZIO_LOGS_TOKEN }} \
--set secrets.logzioRegion=us \
logzio-logs-collector .
- name: run log generator
run: |
kubectl apply -f tests/resources/logsgen.yaml
kubectl rollout status deployment/log-generator --timeout=300s
- name: sleep
run: sleep 120

- name: Run Go Tests
env:
LOGZIO_LOGS_API_TOKEN: ${{ secrets.LOGZIO_LOGS_API_TOKEN }}
run: |
go get go.uber.org/zap
go test -v ./tests/logs_e2e_test.go ./tests/common.go
- name: Cleanup Environment
run: |
helm uninstall logzio-logs-collector
- name: Delete Kind cluster
if: always()
run: kind delete cluster --name kind-${{ github.run_id }}
90 changes: 90 additions & 0 deletions .github/workflows/logzio-telemetry-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Test Logzio Telemetry Helm Chart on Kind Kubernetes Environment

on:
pull_request:
branches:
- main
paths:
- 'charts/logzio-k8s-telemetry/**'
jobs:
test-helm-chart:
name: Test Helm Chart on Kind
runs-on: ubuntu-latest
strategy:
matrix:
mode: ['daemonset', 'standalone']
steps:
- name: Generate random id
id: random_id
run: echo "::set-output name=rand::$(echo $RANDOM)"

- name: Set ENV_ID
run: echo "ENV_ID=telemetry-test-run-${{ steps.random_id.outputs.rand }}-${{ matrix.mode }}" >> $GITHUB_ENV
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.20'

- name: Set up Helm
uses: azure/[email protected]

- name: Set up kubectl
uses: azure/setup-kubectl@v3

- name: Install Kind
run: |
curl -Lo ./kind "https://kind.sigs.k8s.io/dl/v0.11.1/kind-Linux-amd64"
chmod +x ./kind
mv ./kind /usr/local/bin/kind
- name: Create Kind cluster
run: |
kind create cluster --name kind-${{ github.run_id }}-${{ matrix.mode }}
kubectl cluster-info
- name: Deploy Helm Chart
run: |
cd charts/logzio-telemetry
helm dependency build
helm upgrade --install \
--set traces.enabled=true \
--set spm.enabled=true \
--set metrics.enabled=true \
--set secrets.TracesToken=${{ secrets.LOGZIO_TRACES_TOKEN }} \
--set secrets.SpmToken=${{ secrets.LOGZIO_METRICS_TOKEN }} \
--set secrets.MetricsToken=${{ secrets.LOGZIO_METRICS_TOKEN }} \
--set secrets.ListenerHost=https://listener.logz.io:8053 \
--set secrets.p8s_logzio_name=${{ env.ENV_ID }} \
--set secrets.env_id=${{ env.ENV_ID }} \
--set mode=${{ matrix.mode }} \
logzio-k8s-telemetry .
kubectl rollout status deployment/logzio-k8s-telemetry-otel-collector-standalone --timeout=300s
kubectl rollout status deployment/logzio-k8s-telemetry-otel-collector-spm --timeout=300s
- name: run trace generator
run: |
kubectl apply -f tests/resources/tracegen.yaml
kubectl rollout status deployment/trace-gen --timeout=300s
- name: sleep for 2 minutes
run: sleep 120

- name: Run Go Tests
env:
LOGZIO_METRICS_API_KEY: ${{ secrets.LOGZIO_METRICS_API_KEY }}
LOGZIO_TRACES_API_KEY: ${{ secrets.LOGZIO_TRACES_API_KEY }}
run: |
go get go.uber.org/zap
go test -v ./tests/traces_e2e_test.go ./tests/common.go
go test -v ./tests/metrics_e2e_test.go ./tests/common.go
- name: Cleanup Environment
run: |
helm uninstall logzio-k8s-telemetry
- name: Delete Kind cluster
if: always()
run: kind delete cluster --name kind-${{ github.run_id }}-${{ matrix.mode }}

8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module github.com/logzio/logzio-helm

go 1.19

require (
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
51 changes: 51 additions & 0 deletions tests/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package tests

import (
"go.uber.org/zap"
"strings"
)

const (
BaseLogzioApiUrl = "https://api.logz.io/v1"
QueryTemplate = `{
"query": {
"query_string": {
"query": "{{QUERY}}"
}
},
"from": 0,
"size": 100,
"sort": [
{
"@timestamp": {
"order": "desc"
}
}
],
"_source": true,
"docvalue_fields": [
"@timestamp"
],
"version": true,
"stored_fields": [
"*"
],
"highlight": {},
"aggregations": {
"byType": {
"terms": {
"field": "type",
"size": 5
}
}
}
}`
)

func formatQuery(query string) string {
return strings.Replace(QueryTemplate, "{{QUERY}}", query, 1)
}

var (
logger, _ = zap.NewProduction()
)
94 changes: 94 additions & 0 deletions tests/logs_e2e_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package tests

import (
"bytes"
"encoding/json"
"fmt"
"go.uber.org/zap"
"io"
"net/http"
"os"
"testing"
)

type LogResponse struct {
Hits struct {
Total int `json:"total"`
Hits []struct {
Source struct {
ContainerImageTag string `json:"container_image_tag"`
ContainerImageName string `json:"container_image_name"`
ContainerName string `json:"k8s_container_name"`
NamespaceName string `json:"k8s_namespace_name"`
PodName string `json:"k8s_pod_name"`
PodUID string `json:"k8s_pod_uid"`
NodeName string `json:"k8s_node_name"`
LogLevel string `json:"log_level"`
} `json:"_source"`
} `json:"hits"`
} `json:"hits"`
}

func TestLogzioMonitoringLogs(t *testing.T) {
logsApiKey := os.Getenv("LOGZIO_LOGS_API_KEY")
if logsApiKey == "" {
t.Fatalf("LOGZIO_LOGS_API_KEY environment variable not set")
}

logResponse, err := fetchLogs(logsApiKey)
if err != nil {
t.Fatalf("Failed to fetch logs: %v", err)
}

if logResponse.Hits.Total == 0 {
t.Errorf("No logs found")
}

for _, hit := range logResponse.Hits.Hits {
kubernetes := hit.Source
if kubernetes.ContainerImageTag == "" || kubernetes.ContainerName == "" || kubernetes.NamespaceName == "" || kubernetes.PodName == "" || kubernetes.PodUID == "" || kubernetes.NodeName == "" || kubernetes.ContainerImageName == "" || kubernetes.LogLevel == "" {
logger.Error("Missing log fields", zap.Any("log", hit))
t.Errorf("Missing log fields")
break
}
}
}

func fetchLogs(logsApiKey string) (*LogResponse, error) {
url := fmt.Sprintf("%s/search", BaseLogzioApiUrl)
client := &http.Client{}
envID := os.Getenv("ENV_ID")
query := fmt.Sprintf("env_id:%s AND type:agent-k8s AND k8s_deployment_name:log-generator", envID)
formattedQuery := formatQuery(query)
logger.Info("sending api request", zap.String("url", url), zap.String("query", query))
req, err := http.NewRequest("POST", url, bytes.NewBufferString(formattedQuery))
if err != nil {
return nil, err
}
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-TOKEN", logsApiKey)

resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

var logResponse LogResponse
err = json.Unmarshal(body, &logResponse)
if err != nil {
return nil, err
}

return &logResponse, nil
}
Loading

0 comments on commit ab68b71

Please sign in to comment.