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 }