mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-13 03:42:35 -06:00
a80c3f0c27
Fixes #5155 Signed-off-by: Anders Eknert <anders@eknert.com>
182 lines
4.4 KiB
Go
182 lines
4.4 KiB
Go
// Copyright 2018 The OPA Authors. All rights reserved.
|
|
// Use of this source code is governed by an Apache2
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package logs
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/open-policy-agent/opa/metrics"
|
|
)
|
|
|
|
func TestChunkEncoder(t *testing.T) {
|
|
|
|
enc := newChunkEncoder(1000)
|
|
var result interface{} = false
|
|
var expInput interface{} = map[string]interface{}{"method": "GET"}
|
|
ts, err := time.Parse(time.RFC3339Nano, "2018-01-01T12:00:00.123456Z")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
event := EventV1{
|
|
Labels: map[string]string{
|
|
"id": "test-instance-id",
|
|
"app": "example-app",
|
|
},
|
|
Revision: "a",
|
|
DecisionID: "a",
|
|
Path: "foo/bar",
|
|
Input: &expInput,
|
|
Result: &result,
|
|
RequestedBy: "test",
|
|
Timestamp: ts,
|
|
}
|
|
|
|
bs, err := enc.Write(event)
|
|
if bs != nil || err != nil {
|
|
t.Fatalf("Unexpected error or chunk produced: err: %v", err)
|
|
}
|
|
|
|
bs, err = enc.Flush()
|
|
if bs == nil || err != nil {
|
|
t.Fatalf("Unexpected error or NO chunk produced: err: %v", err)
|
|
}
|
|
|
|
bs, err = enc.Flush()
|
|
if bs != nil || err != nil {
|
|
t.Fatalf("Unexpected error chunk produced: err: %v", err)
|
|
|
|
}
|
|
}
|
|
|
|
func TestChunkEncoderSizeLimit(t *testing.T) {
|
|
enc := newChunkEncoder(1).WithMetrics(metrics.New())
|
|
var result interface{} = false
|
|
var expInput interface{} = map[string]interface{}{"method": "GET"}
|
|
ts, err := time.Parse(time.RFC3339Nano, "2018-01-01T12:00:00.123456Z")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
event := EventV1{
|
|
Labels: map[string]string{
|
|
"id": "test-instance-id",
|
|
"app": "example-app",
|
|
},
|
|
DecisionID: "123",
|
|
Path: "foo/bar",
|
|
Input: &expInput,
|
|
Result: &result,
|
|
RequestedBy: "test",
|
|
Timestamp: ts,
|
|
}
|
|
_, err = enc.Write(event)
|
|
if err == nil {
|
|
t.Error("Expected error as upload chunk size exceeds configured limit")
|
|
}
|
|
expected := "upload chunk size (200) exceeds upload_size_limit_bytes (1)"
|
|
if err.Error() != expected {
|
|
t.Errorf("expected: '%s', got: '%s'", expected, err.Error())
|
|
}
|
|
}
|
|
|
|
func TestChunkEncoderAdaptive(t *testing.T) {
|
|
|
|
enc := newChunkEncoder(1000).WithMetrics(metrics.New())
|
|
var result interface{} = false
|
|
var expInput interface{} = map[string]interface{}{"method": "GET"}
|
|
ts, err := time.Parse(time.RFC3339Nano, "2018-01-01T12:00:00.123456Z")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
var chunks [][]byte
|
|
numEvents := 400
|
|
for i := 0; i < numEvents; i++ {
|
|
|
|
bundles := map[string]BundleInfoV1{}
|
|
bundles["authz"] = BundleInfoV1{Revision: fmt.Sprint(i)}
|
|
|
|
event := EventV1{
|
|
Labels: map[string]string{
|
|
"id": "test-instance-id",
|
|
"app": "example-app",
|
|
},
|
|
Bundles: bundles,
|
|
DecisionID: fmt.Sprint(i),
|
|
Path: "foo/bar",
|
|
Input: &expInput,
|
|
Result: &result,
|
|
RequestedBy: "test",
|
|
Timestamp: ts,
|
|
}
|
|
|
|
chunk, err := enc.Write(event)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if chunk != nil {
|
|
chunks = append(chunks, chunk...)
|
|
}
|
|
}
|
|
|
|
// decode the chunks and check the number of events is equal to the encoded events
|
|
|
|
numEventsActual := decodeChunks(t, chunks)
|
|
|
|
// flush the encoder
|
|
for {
|
|
bs, err := enc.Flush()
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error: %v", err)
|
|
}
|
|
|
|
if len(bs) == 0 {
|
|
break
|
|
}
|
|
|
|
numEventsActual += decodeChunks(t, bs)
|
|
}
|
|
|
|
if numEvents != numEventsActual {
|
|
t.Fatalf("Expected %v events but got %v", numEvents, numEventsActual)
|
|
}
|
|
|
|
actualScaleUpEvents := enc.metrics.Counter(encSoftLimitScaleUpCounterName).Value().(uint64)
|
|
actualScaleDownEvents := enc.metrics.Counter(encSoftLimitScaleDownCounterName).Value().(uint64)
|
|
actualEquiEvents := enc.metrics.Counter(encSoftLimitStableCounterName).Value().(uint64)
|
|
|
|
expectedScaleUpEvents := uint64(8)
|
|
expectedScaleDownEvents := uint64(3)
|
|
expectedEquiEvents := uint64(0)
|
|
|
|
if actualScaleUpEvents != expectedScaleUpEvents {
|
|
t.Fatalf("Expected scale up events %v but got %v", expectedScaleUpEvents, actualScaleUpEvents)
|
|
}
|
|
|
|
if actualScaleDownEvents != expectedScaleDownEvents {
|
|
t.Fatalf("Expected scale down events %v but got %v", expectedScaleDownEvents, actualScaleDownEvents)
|
|
}
|
|
|
|
if actualEquiEvents != expectedEquiEvents {
|
|
t.Fatalf("Expected equilibrium events %v but got %v", expectedEquiEvents, actualEquiEvents)
|
|
}
|
|
}
|
|
|
|
func decodeChunks(t *testing.T, bs [][]byte) int {
|
|
t.Helper()
|
|
|
|
numEvents := 0
|
|
for _, chunk := range bs {
|
|
events, err := newChunkDecoder(chunk).decode()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
numEvents += len(events)
|
|
}
|
|
return numEvents
|
|
}
|