github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/pkg/sink/cloudstorage/config_test.go (about) 1 // Copyright 2022 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package cloudstorage 15 16 import ( 17 "context" 18 "net/url" 19 "testing" 20 "time" 21 22 "github.com/aws/aws-sdk-go/aws" 23 "github.com/pingcap/tiflow/pkg/config" 24 "github.com/stretchr/testify/require" 25 ) 26 27 func TestConfigApply(t *testing.T) { 28 expected := NewConfig() 29 expected.WorkerCount = 32 30 expected.FlushInterval = 10 * time.Second 31 expected.FileSize = 16 * 1024 * 1024 32 expected.FileIndexWidth = config.DefaultFileIndexWidth 33 expected.DateSeparator = config.DateSeparatorDay.String() 34 expected.EnablePartitionSeparator = true 35 expected.FlushConcurrency = 1 36 uri := "s3://bucket/prefix?worker-count=32&flush-interval=10s&file-size=16777216&protocol=csv" 37 sinkURI, err := url.Parse(uri) 38 require.Nil(t, err) 39 40 replicaConfig := config.GetDefaultReplicaConfig() 41 err = replicaConfig.ValidateAndAdjust(sinkURI) 42 require.NoError(t, err) 43 cfg := NewConfig() 44 err = cfg.Apply(context.TODO(), sinkURI, replicaConfig) 45 require.Nil(t, err) 46 require.Equal(t, expected, cfg) 47 } 48 49 func TestVerifySinkURIParams(t *testing.T) { 50 testCases := []struct { 51 name string 52 uri string 53 expectedErr string 54 }{ 55 { 56 name: "valid sink uri with local/nfs scheme", 57 uri: "file://tmp/test", 58 expectedErr: "", 59 }, 60 { 61 name: "valid sink uri with s3 scheme", 62 uri: "s3://bucket/prefix", 63 expectedErr: "", 64 }, 65 { 66 name: "valid sink uri with gcs scheme", 67 uri: "gcs://bucket/prefix", 68 expectedErr: "", 69 }, 70 { 71 name: "valid sink uri with azblob scheme", 72 uri: "azblob://bucket/prefix", 73 expectedErr: "", 74 }, 75 { 76 name: "sink uri with valid scheme, worker-count, flush-interval and file-size", 77 uri: "s3://bucket/prefix?worker-count=64&flush-interval=1m30s&file-size=33554432", 78 expectedErr: "", 79 }, 80 { 81 name: "invalid sink uri with unknown storage scheme", 82 uri: "xxx://tmp/test", 83 expectedErr: "can't create cloud storage sink with unsupported scheme", 84 }, 85 { 86 name: "invalid sink uri with worker-count number less than lower limit", 87 uri: "file://tmp/test?worker-count=-1", 88 expectedErr: "invalid worker-count -1, it must be greater than 0", 89 }, 90 { 91 name: "invalid sink uri with worker-count number greater than upper limit", 92 uri: "s3://bucket/prefix?worker-count=10000", 93 expectedErr: "", 94 }, 95 { 96 name: "invalid sink uri with flush-interval less than lower limit", 97 uri: "s3://bucket/prefix?flush-interval=-10s", 98 expectedErr: "", 99 }, 100 { 101 name: "invalid sink uri with flush-interval greater than upper limit", 102 uri: "s3://bucket/prefix?flush=interval=1h", 103 expectedErr: "", 104 }, 105 { 106 name: "invalid sink uri with file-size less than lower limit", 107 uri: "s3://bucket/prefix?file-size=1024", 108 expectedErr: "", 109 }, 110 { 111 name: "invalid sink uri with file-size greater than upper limit", 112 uri: "s3://bucket/prefix?file-size=1073741824", 113 expectedErr: "", 114 }, 115 } 116 117 for _, tc := range testCases { 118 sinkURI, err := url.Parse(tc.uri) 119 require.Nil(t, err) 120 cfg := NewConfig() 121 err = cfg.Apply(context.TODO(), sinkURI, config.GetDefaultReplicaConfig()) 122 if tc.expectedErr == "" { 123 require.Nil(t, err) 124 require.LessOrEqual(t, cfg.WorkerCount, maxWorkerCount) 125 require.LessOrEqual(t, cfg.FlushInterval, maxFlushInterval) 126 require.LessOrEqual(t, cfg.FileSize, maxFileSize) 127 } else { 128 require.Regexp(t, tc.expectedErr, err) 129 } 130 } 131 } 132 133 func TestMergeConfig(t *testing.T) { 134 uri := "s3://bucket/prefix" 135 sinkURI, err := url.Parse(uri) 136 require.NoError(t, err) 137 replicaConfig := config.GetDefaultReplicaConfig() 138 replicaConfig.Sink.CloudStorageConfig = &config.CloudStorageConfig{ 139 WorkerCount: aws.Int(12), 140 FileSize: aws.Int(1485760), 141 FlushInterval: aws.String("1m2s"), 142 OutputColumnID: aws.Bool(false), 143 } 144 c := NewConfig() 145 err = c.Apply(context.TODO(), sinkURI, replicaConfig) 146 require.NoError(t, err) 147 require.Equal(t, 12, c.WorkerCount) 148 require.Equal(t, 1485760, c.FileSize) 149 require.Equal(t, "1m2s", c.FlushInterval.String()) 150 151 // test override 152 uri = "s3://bucket/prefix?worker-count=64&flush-interval=2m2s&file-size=33554432" 153 sinkURI, err = url.Parse(uri) 154 require.NoError(t, err) 155 replicaConfig.Sink.CloudStorageConfig = &config.CloudStorageConfig{ 156 WorkerCount: aws.Int(12), 157 FileSize: aws.Int(10485760), 158 FlushInterval: aws.String("1m2s"), 159 OutputColumnID: aws.Bool(false), 160 } 161 c = NewConfig() 162 err = c.Apply(context.TODO(), sinkURI, replicaConfig) 163 require.NoError(t, err) 164 require.Equal(t, 64, c.WorkerCount) 165 require.Equal(t, 33554432, c.FileSize) 166 require.Equal(t, "2m2s", c.FlushInterval.String()) 167 }