storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/bucket/bandwidth/monitor_test.go (about)

     1  /*
     2   * MinIO Cloud Storage, (C) 2020 MinIO, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package bandwidth
    18  
    19  import (
    20  	"context"
    21  	"reflect"
    22  	"testing"
    23  	"time"
    24  
    25  	"storj.io/minio/pkg/bandwidth"
    26  )
    27  
    28  const (
    29  	oneMiB uint64 = 1024 * 1024
    30  )
    31  
    32  func TestMonitor_GetThrottle(t *testing.T) {
    33  	type fields struct {
    34  		bucketThrottles map[string]*throttle
    35  		bucket          string
    36  		bpi             int64
    37  	}
    38  	t1 := newThrottle(context.Background(), 100, 1024*1024)
    39  	t2 := newThrottle(context.Background(), 200, 1024*1024)
    40  	tests := []struct {
    41  		name   string
    42  		fields fields
    43  		want   *throttle
    44  	}{
    45  		{
    46  			name: "Existing",
    47  			fields: fields{
    48  				bucketThrottles: map[string]*throttle{"bucket": t1},
    49  				bucket:          "bucket",
    50  				bpi:             100,
    51  			},
    52  			want: t1,
    53  		},
    54  		{
    55  			name: "new",
    56  			fields: fields{
    57  				bucketThrottles: map[string]*throttle{"bucket": t1},
    58  				bucket:          "bucket2",
    59  				bpi:             200,
    60  			},
    61  			want: t2,
    62  		},
    63  	}
    64  	for _, tt := range tests {
    65  		tt := tt
    66  		t.Run(tt.name, func(t *testing.T) {
    67  			t.Parallel()
    68  			m := &Monitor{
    69  				bucketThrottle: tt.fields.bucketThrottles,
    70  			}
    71  			if got := m.throttleBandwidth(context.Background(), tt.fields.bucket, tt.fields.bpi, 1024*1024); got.bytesPerInterval != tt.want.bytesPerInterval {
    72  				t.Errorf("throttleBandwidth() = %v, want %v", got, tt.want)
    73  			}
    74  		})
    75  	}
    76  }
    77  
    78  func TestMonitor_GetReport(t *testing.T) {
    79  	type fields struct {
    80  		activeBuckets map[string]*bucketMeasurement
    81  		endTime       time.Time
    82  		update2       uint64
    83  		endTime2      time.Time
    84  	}
    85  	start := time.Now()
    86  	m0 := newBucketMeasurement(start)
    87  	m0.incrementBytes(0)
    88  	m1MiBPS := newBucketMeasurement(start)
    89  	m1MiBPS.incrementBytes(oneMiB)
    90  	tests := []struct {
    91  		name   string
    92  		fields fields
    93  		want   *bandwidth.Report
    94  		want2  *bandwidth.Report
    95  	}{
    96  		{
    97  			name: "ZeroToOne",
    98  			fields: fields{
    99  				activeBuckets: map[string]*bucketMeasurement{
   100  					"bucket": m0,
   101  				},
   102  				endTime:  start.Add(1 * time.Second),
   103  				update2:  oneMiB,
   104  				endTime2: start.Add(2 * time.Second),
   105  			},
   106  			want: &bandwidth.Report{
   107  				BucketStats: map[string]bandwidth.Details{"bucket": {LimitInBytesPerSecond: 1024 * 1024, CurrentBandwidthInBytesPerSecond: 0}},
   108  			},
   109  			want2: &bandwidth.Report{
   110  				BucketStats: map[string]bandwidth.Details{"bucket": {LimitInBytesPerSecond: 1024 * 1024, CurrentBandwidthInBytesPerSecond: (1024 * 1024) / start.Add(2*time.Second).Sub(start.Add(1*time.Second)).Seconds()}},
   111  			},
   112  		},
   113  		{
   114  			name: "OneToTwo",
   115  			fields: fields{
   116  				activeBuckets: map[string]*bucketMeasurement{
   117  					"bucket": m1MiBPS,
   118  				},
   119  				endTime:  start.Add(1 * time.Second),
   120  				update2:  2 * oneMiB,
   121  				endTime2: start.Add(2 * time.Second),
   122  			},
   123  			want: &bandwidth.Report{
   124  				BucketStats: map[string]bandwidth.Details{"bucket": {LimitInBytesPerSecond: 1024 * 1024, CurrentBandwidthInBytesPerSecond: float64(oneMiB)}},
   125  			},
   126  			want2: &bandwidth.Report{
   127  				BucketStats: map[string]bandwidth.Details{"bucket": {
   128  					LimitInBytesPerSecond:            1024 * 1024,
   129  					CurrentBandwidthInBytesPerSecond: exponentialMovingAverage(betaBucket, float64(oneMiB), 2*float64(oneMiB))}},
   130  			},
   131  		},
   132  	}
   133  	for _, tt := range tests {
   134  		tt := tt
   135  		t.Run(tt.name, func(t *testing.T) {
   136  			t.Parallel()
   137  			thr := throttle{
   138  				bytesPerSecond:   1024 * 1024,
   139  				clusterBandwidth: 1024 * 1024,
   140  			}
   141  			m := &Monitor{
   142  				activeBuckets:  tt.fields.activeBuckets,
   143  				bucketThrottle: map[string]*throttle{"bucket": &thr},
   144  			}
   145  			m.activeBuckets["bucket"].updateExponentialMovingAverage(tt.fields.endTime)
   146  			got := m.GetReport(SelectBuckets())
   147  			if !reflect.DeepEqual(got, tt.want) {
   148  				t.Errorf("GetReport() = %v, want %v", got, tt.want)
   149  			}
   150  			m.activeBuckets["bucket"].incrementBytes(tt.fields.update2)
   151  			m.activeBuckets["bucket"].updateExponentialMovingAverage(tt.fields.endTime2)
   152  			got = m.GetReport(SelectBuckets())
   153  			if !reflect.DeepEqual(got, tt.want2) {
   154  				t.Errorf("GetReport() = %v, want %v", got, tt.want2)
   155  			}
   156  		})
   157  	}
   158  }