github.com/kubeshop/testkube@v1.17.23/pkg/logs/adapter/minio_test.go (about)

     1  package adapter
     2  
     3  import (
     4  	"bufio"
     5  	"context"
     6  	"encoding/json"
     7  	"fmt"
     8  	"io"
     9  	"math/rand"
    10  	"strconv"
    11  	"sync"
    12  	"sync/atomic"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/minio/minio-go/v7"
    17  	"github.com/stretchr/testify/assert"
    18  
    19  	"github.com/kubeshop/testkube/pkg/logs/events"
    20  	"github.com/kubeshop/testkube/pkg/utils"
    21  )
    22  
    23  const hugeString = "82vbUcyQ0chpR665zbXY2mySOk7DGDFQCF1iLFjDNUYtNV8oQNaX3IYgJR30zBVhmDVjoZDJXO479tGSirHilZWEbzhjKJOdUwGb2HWOSOOjGh5r5wH0EHxRiOp8mBJv2rwdB2SoKF7JTBFgRt9M8F0JKp2Zx5kqh8eOGB1DGj64NLmwIpfuevJSv0wbDLrls5kEL5hHkszXPsuufVjJBsjNrxCoafuk93L2jE3ivVrMlkmLd9XAWKdop0oo0yRMJ9Vs1T5SZTkM6KXJB5hY3c14NsoPiG9Ay4EZmXrGpzGWI3RLAU6snXL8kV9sVLCG5DuRDnW047VR8eb78fpVj8YY3o9xpZd7xYPAhsmK0SwznHfrb0etAqdjQO6LFS9Blwre3G94DG5scVFH8RfteVNgKJXa8lTp8kKjtQLKNNA9mqyWfJ7uy8yjnVKwl7rodKqdtU6wjH2hf597MXA3roIS2xVhFpsCAVDybo9TVvZpoGfE9povhApoUR6Rmae9zvXPRoDbClOrvDElFkfgkJFzuoY2rPoV3dKuiTNwhYgPm36WPRk3SeFf2NiBQnWJBvjbRMIk5DsGfxcEiXQBfDvY4hgFctjwZ3USvWGriqT1cPsJ90LMLxbp38TRD1KVJ8ZgpqdvKTTi8dBqgEtob7okhdrkOahHJ3EKPtqV4PmaHvXSaIJvDG9c8jza64wxYBwMkHGt22i3HhCcIi8KmmfVo1ruqQLqKvINJg8eD5rKGV1mX9IipQcnrqADYnAj1wls7NSxsL0VZZm2pxRaGN494o2LCicHGEcOYkVLHufXY4Gv3friOIZSrT1r3NUgDBufpXWiG2b02TrRyFhgwRSS1a2OyMjHkT9tALmlIwFGF5HdaZphN6Mo5TFGdJyp65YU1scnlSGAVXzVdhsoD0RDZPSetdK2fzJC20kncaujAujHtSKnXrJNIhObnOjgMhCkx5E4z0oIH26DlfrbxS7k5SBQb1Zo3papQOk4uTNIdMBW4cE3V7AB8r6v4en3"
    24  
    25  func init() {
    26  	rand.New(rand.NewSource(time.Now().UnixNano()))
    27  }
    28  
    29  var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
    30  
    31  func RandString(n int) string {
    32  	b := make([]rune, n)
    33  	for i := range b {
    34  		b[i] = letterRunes[rand.Intn(len(letterRunes))]
    35  	}
    36  	return string(b)
    37  }
    38  
    39  func TestLogs(t *testing.T) {
    40  	t.Skip("skipping test")
    41  	ctx := context.Background()
    42  	consumer, _ := NewMinioAdapter("localhost:9000", "minio", "minio123", "", "", "test-1", false, false, "", "", "")
    43  	id := "test-bla"
    44  	for i := 0; i < 1000; i++ {
    45  		fmt.Println("sending", i)
    46  		consumer.Notify(ctx, id, events.Log{Time: time.Now(),
    47  			Content: fmt.Sprintf("Test %d: %s", i, hugeString),
    48  			Type_:   "test", Source: strconv.Itoa(i)})
    49  		time.Sleep(100 * time.Millisecond)
    50  	}
    51  	err := consumer.Stop(ctx, id)
    52  	assert.NoError(t, err)
    53  }
    54  
    55  func BenchmarkLogs(b *testing.B) {
    56  	ctx := context.Background()
    57  	randomString := RandString(5)
    58  	bucket := "test-bench"
    59  	consumer, _ := NewMinioAdapter("localhost:9000", "minio", "minio123", "", "", bucket, false, false, "", "", "")
    60  	id := "test-bench" + "-" + randomString + "-" + strconv.Itoa(b.N)
    61  	totalSize := 0
    62  	for i := 0; i < b.N; i++ {
    63  		consumer.Notify(ctx, id, events.Log{Time: time.Now(),
    64  			Content: fmt.Sprintf("Test %d: %s", i, hugeString),
    65  			Type_:   "test", Source: strconv.Itoa(i)})
    66  		totalSize += len(hugeString)
    67  	}
    68  	sizeInMB := float64(totalSize) / 1024 / 1024
    69  	err := consumer.Stop(ctx, id)
    70  	assert.NoError(b, err)
    71  	b.Logf("Total size for %s logs is %f MB", id, sizeInMB)
    72  }
    73  
    74  func BenchmarkLogs2(b *testing.B) {
    75  	bucket := "test-bench"
    76  	consumer, _ := NewMinioAdapter("localhost:9000", "minio", "minio123", "", "", bucket, false, false, "", "", "")
    77  	idChan := make(chan string, 100)
    78  	go verifyConsumer(idChan, bucket, consumer.minioClient)
    79  	var counter atomic.Int32
    80  	var wg sync.WaitGroup
    81  	for i := 0; i < 10; i++ {
    82  		wg.Add(1)
    83  		go func() {
    84  			defer wg.Done()
    85  			randomString := strconv.Itoa(int(counter.Add(1)))
    86  			id := "test-bench" + "-" + randomString
    87  			testOneConsumer(consumer, id)
    88  			idChan <- id
    89  		}()
    90  	}
    91  	wg.Wait()
    92  }
    93  
    94  func testOneConsumer(consumer *MinioAdapter, id string) {
    95  	ctx := context.Background()
    96  	fmt.Println("#####starting", id)
    97  	totalSize := 0
    98  	numberOFLogs := rand.Intn(100000)
    99  	for i := 0; i < numberOFLogs; i++ {
   100  		consumer.Notify(ctx, id, events.Log{Time: time.Now(),
   101  			Content: fmt.Sprintf("Test %d: %s", i, hugeString),
   102  			Type_:   "test", Source: strconv.Itoa(i)})
   103  		totalSize += len(hugeString)
   104  		time.Sleep(time.Duration(rand.Intn(10)) * time.Millisecond)
   105  	}
   106  	sizeInMB := float64(totalSize) / 1024 / 1024
   107  	err := consumer.Stop(ctx, id)
   108  	if err != nil {
   109  		fmt.Println("#####error stopping", err)
   110  	}
   111  	fmt.Printf("#####Total size for %s logs is %f MB\n\n\n", id, sizeInMB)
   112  }
   113  
   114  func verifyConsumer(idChan chan string, bucket string, minioClient *minio.Client) {
   115  	okSlice := make([]string, 0)
   116  	notOkSlice := make([]string, 0)
   117  	for id := range idChan {
   118  		reader, err := minioClient.GetObject(context.Background(), bucket, id, minio.GetObjectOptions{})
   119  		if err != nil {
   120  			fmt.Println("######error getting object", err)
   121  		}
   122  		count := 0
   123  
   124  		r := bufio.NewReader(reader)
   125  		isOk := true
   126  		for {
   127  			line, err := utils.ReadLongLine(r)
   128  			if err != nil {
   129  				if err == io.EOF {
   130  					err = nil
   131  				}
   132  				break
   133  			}
   134  			var LogChunk events.Log
   135  			err = json.Unmarshal(line, &LogChunk)
   136  			if err != nil {
   137  				fmt.Printf("for id %s error %v unmarshalling %s\n\n\n", id, err, string(line))
   138  				isOk = false
   139  				break
   140  			}
   141  			if LogChunk.Source == "" || LogChunk.Source != strconv.Itoa(count) {
   142  				fmt.Printf("for id %s not equal for count %d line %s \n logChunk %+v\n\n\n", id, count, string(line), LogChunk)
   143  				isOk = false
   144  				break
   145  			}
   146  			count++
   147  		}
   148  		if isOk {
   149  			okSlice = append(okSlice, id)
   150  		} else {
   151  			notOkSlice = append(notOkSlice, id)
   152  		}
   153  	}
   154  	fmt.Println("##### number of ok", len(okSlice))
   155  	fmt.Println("#####verified ok", okSlice)
   156  	fmt.Println("##### number of not ok", len(notOkSlice))
   157  	fmt.Println("#####verified not ok", notOkSlice)
   158  }
   159  
   160  func DoRunBenchmark() {
   161  	numberOfConsumers := 100
   162  	bucket := "test-bench"
   163  	consumer, _ := NewMinioAdapter("testkube-minio-service-testkube:9000", "minio", "minio123", "", "", bucket, false, false, "", "", "")
   164  
   165  	idChan := make(chan string, numberOfConsumers)
   166  	DoRunBenchmark2(idChan, numberOfConsumers, consumer)
   167  	verifyConsumer(idChan, bucket, consumer.minioClient)
   168  }
   169  
   170  func DoRunBenchmark2(idChan chan string, numberOfConsumers int, consumer *MinioAdapter) {
   171  	var counter atomic.Int32
   172  	var wg sync.WaitGroup
   173  	for i := 0; i < numberOfConsumers; i++ {
   174  		wg.Add(1)
   175  		go func() {
   176  			defer wg.Done()
   177  			randomString := strconv.Itoa(int(counter.Add(1)))
   178  			id := "test-bench" + "-" + randomString
   179  			testOneConsumer(consumer, id)
   180  			idChan <- id
   181  		}()
   182  	}
   183  	wg.Wait()
   184  	close(idChan)
   185  	fmt.Printf("#####Done buffInfo is %+v\n\n\n", consumer.buffInfos)
   186  }