github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/bucket/bandwidth/monitor_test.go (about)

     1  // Copyright (c) 2015-2021 MinIO, Inc.
     2  //
     3  // This file is part of MinIO Object Storage stack
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package bandwidth
    19  
    20  import (
    21  	"reflect"
    22  	"testing"
    23  	"time"
    24  )
    25  
    26  const (
    27  	oneMiB uint64 = 1024 * 1024
    28  )
    29  
    30  func TestMonitor_GetReport(t *testing.T) {
    31  	type fields struct {
    32  		activeBuckets map[BucketOptions]*bucketMeasurement
    33  		endTime       time.Time
    34  		update2       uint64
    35  		endTime2      time.Time
    36  	}
    37  	start := time.Now()
    38  	m0 := newBucketMeasurement(start)
    39  	m0.incrementBytes(0)
    40  	m1MiBPS := newBucketMeasurement(start)
    41  	m1MiBPS.incrementBytes(oneMiB)
    42  
    43  	test1Want := make(map[BucketOptions]Details)
    44  	test1Want[BucketOptions{Name: "bucket", ReplicationARN: "arn"}] = Details{LimitInBytesPerSecond: 1024 * 1024, CurrentBandwidthInBytesPerSecond: 0}
    45  	test1Want2 := make(map[BucketOptions]Details)
    46  	test1Want2[BucketOptions{Name: "bucket", ReplicationARN: "arn"}] = Details{
    47  		LimitInBytesPerSecond:            1024 * 1024,
    48  		CurrentBandwidthInBytesPerSecond: (1024 * 1024) / start.Add(2*time.Second).Sub(start.Add(1*time.Second)).Seconds(),
    49  	}
    50  
    51  	test2Want := make(map[BucketOptions]Details)
    52  	test2Want[BucketOptions{Name: "bucket", ReplicationARN: "arn"}] = Details{LimitInBytesPerSecond: 1024 * 1024, CurrentBandwidthInBytesPerSecond: float64(oneMiB)}
    53  	test2Want2 := make(map[BucketOptions]Details)
    54  	test2Want2[BucketOptions{Name: "bucket", ReplicationARN: "arn"}] = Details{
    55  		LimitInBytesPerSecond:            1024 * 1024,
    56  		CurrentBandwidthInBytesPerSecond: exponentialMovingAverage(betaBucket, float64(oneMiB), 2*float64(oneMiB)),
    57  	}
    58  
    59  	test1ActiveBuckets := make(map[BucketOptions]*bucketMeasurement)
    60  	test1ActiveBuckets[BucketOptions{Name: "bucket", ReplicationARN: "arn"}] = m0
    61  	test1ActiveBuckets2 := make(map[BucketOptions]*bucketMeasurement)
    62  	test1ActiveBuckets2[BucketOptions{Name: "bucket", ReplicationARN: "arn"}] = m1MiBPS
    63  
    64  	tests := []struct {
    65  		name   string
    66  		fields fields
    67  		want   *BucketBandwidthReport
    68  		want2  *BucketBandwidthReport
    69  	}{
    70  		{
    71  			name: "ZeroToOne",
    72  			fields: fields{
    73  				activeBuckets: test1ActiveBuckets,
    74  				endTime:       start.Add(1 * time.Second),
    75  				update2:       oneMiB,
    76  				endTime2:      start.Add(2 * time.Second),
    77  			},
    78  			want: &BucketBandwidthReport{
    79  				BucketStats: test1Want,
    80  			},
    81  			want2: &BucketBandwidthReport{
    82  				BucketStats: test1Want2,
    83  			},
    84  		},
    85  		{
    86  			name: "OneToTwo",
    87  			fields: fields{
    88  				activeBuckets: test1ActiveBuckets2,
    89  				endTime:       start.Add(1 * time.Second),
    90  				update2:       2 * oneMiB,
    91  				endTime2:      start.Add(2 * time.Second),
    92  			},
    93  			want: &BucketBandwidthReport{
    94  				BucketStats: test2Want,
    95  			},
    96  			want2: &BucketBandwidthReport{
    97  				BucketStats: test2Want2,
    98  			},
    99  		},
   100  	}
   101  	for _, tt := range tests {
   102  		tt := tt
   103  		t.Run(tt.name, func(t *testing.T) {
   104  			t.Parallel()
   105  			thr := bucketThrottle{
   106  				NodeBandwidthPerSec: 1024 * 1024,
   107  			}
   108  			th := make(map[BucketOptions]*bucketThrottle)
   109  			th[BucketOptions{Name: "bucket", ReplicationARN: "arn"}] = &thr
   110  			m := &Monitor{
   111  				bucketsMeasurement: tt.fields.activeBuckets,
   112  				bucketsThrottle:    th,
   113  				NodeCount:          1,
   114  			}
   115  			m.bucketsMeasurement[BucketOptions{Name: "bucket", ReplicationARN: "arn"}].updateExponentialMovingAverage(tt.fields.endTime)
   116  			got := m.GetReport(SelectBuckets())
   117  			if !reflect.DeepEqual(got, tt.want) {
   118  				t.Errorf("GetReport() = %v, want %v", got, tt.want)
   119  			}
   120  			m.bucketsMeasurement[BucketOptions{Name: "bucket", ReplicationARN: "arn"}].incrementBytes(tt.fields.update2)
   121  			m.bucketsMeasurement[BucketOptions{Name: "bucket", ReplicationARN: "arn"}].updateExponentialMovingAverage(tt.fields.endTime2)
   122  			got = m.GetReport(SelectBuckets())
   123  			if !reflect.DeepEqual(got.BucketStats, tt.want2.BucketStats) {
   124  				t.Errorf("GetReport() = %v, want %v", got.BucketStats, tt.want2.BucketStats)
   125  			}
   126  		})
   127  	}
   128  }