Skip to content

Commit 1f9df02

Browse files
SNOW-870356: Increase code coverage on CodeCov (#921)
1 parent ea57743 commit 1f9df02

11 files changed

+373
-45
lines changed

assert_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ import (
1010
"testing"
1111
)
1212

13+
func assertNilE(t *testing.T, actual any, descriptions ...string) {
14+
errorOnNonEmpty(t, validateNil(actual, descriptions...))
15+
}
16+
1317
func assertNilF(t *testing.T, actual any, descriptions ...string) {
1418
fatalOnNonEmpty(t, validateNil(actual, descriptions...))
1519
}

auth_test.go

+30
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,36 @@ func TestUnitAuthenticateWithConfigMFA(t *testing.T) {
656656
}
657657
}
658658

659+
func TestUnitAuthenticateWithConfigOkta(t *testing.T) {
660+
var err error
661+
sr := &snowflakeRestful{
662+
Protocol: "https",
663+
Host: "abc.com",
664+
Port: 443,
665+
FuncPostAuthSAML: postAuthSAMLAuthSuccess,
666+
FuncPostAuthOKTA: postAuthOKTASuccess,
667+
FuncGetSSO: getSSOSuccess,
668+
FuncPostAuth: postAuthSuccess,
669+
TokenAccessor: getSimpleTokenAccessor(),
670+
}
671+
sc := getDefaultSnowflakeConn()
672+
sc.cfg.Authenticator = AuthTypeOkta
673+
sc.cfg.OktaURL = &url.URL{
674+
Scheme: "https",
675+
Host: "abc.com",
676+
}
677+
sc.rest = sr
678+
sc.ctx = context.Background()
679+
680+
err = authenticateWithConfig(sc)
681+
assertNilE(t, err, "expected to have no error.")
682+
683+
sr.FuncPostAuthSAML = postAuthSAMLError
684+
err = authenticateWithConfig(sc)
685+
assertNotNilF(t, err, "should have failed at FuncPostAuthSAML.")
686+
assertEqualE(t, err.Error(), "failed to get SAML response")
687+
}
688+
659689
func TestUnitAuthenticateExternalBrowser(t *testing.T) {
660690
var err error
661691
sr := &snowflakeRestful{

authokta.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ func authenticateBySAML(
111111
if tokenURL, err = url.Parse(respd.Data.TokenURL); err != nil {
112112
return nil, fmt.Errorf("failed to parse token URL. %v", respd.Data.TokenURL)
113113
}
114-
if ssoURL, err = url.Parse(respd.Data.TokenURL); err != nil {
115-
return nil, fmt.Errorf("failed to parse ssoURL URL. %v", respd.Data.SSOURL)
114+
if ssoURL, err = url.Parse(respd.Data.SSOURL); err != nil {
115+
return nil, fmt.Errorf("failed to parse SSO URL. %v", respd.Data.SSOURL)
116116
}
117117
if !isPrefixEqual(oktaURL, ssoURL) || !isPrefixEqual(oktaURL, tokenURL) {
118118
return nil, &SnowflakeError{

authokta_test.go

+84-28
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"errors"
88
"net/http"
99
"net/url"
10+
"strconv"
1011
"testing"
1112
"time"
1213
)
@@ -122,6 +123,10 @@ func TestUnitGetSSO(t *testing.T) {
122123
if err != nil {
123124
t.Fatalf("failed to get HTML content. err: %v", err)
124125
}
126+
_, err = getSSO(context.Background(), sr, &url.Values{}, make(map[string]string), "invalid!@url$%^", 0)
127+
if err == nil {
128+
t.Fatal("should have failed to parse URL.")
129+
}
125130
}
126131

127132
func postAuthSAMLError(_ context.Context, _ *snowflakeRestful, _ map[string]string, _ []byte, _ time.Duration) (*authResponse, error) {
@@ -135,6 +140,14 @@ func postAuthSAMLAuthFail(_ context.Context, _ *snowflakeRestful, _ map[string]s
135140
}, nil
136141
}
137142

143+
func postAuthSAMLAuthFailWithCode(_ context.Context, _ *snowflakeRestful, _ map[string]string, _ []byte, _ time.Duration) (*authResponse, error) {
144+
return &authResponse{
145+
Success: false,
146+
Code: strconv.Itoa(ErrCodeIdpConnectionError),
147+
Message: "SAML auth failed",
148+
}, nil
149+
}
150+
138151
func postAuthSAMLAuthSuccessButInvalidURL(_ context.Context, _ *snowflakeRestful, _ map[string]string, _ []byte, _ time.Duration) (*authResponse, error) {
139152
return &authResponse{
140153
Success: true,
@@ -146,6 +159,28 @@ func postAuthSAMLAuthSuccessButInvalidURL(_ context.Context, _ *snowflakeRestful
146159
}, nil
147160
}
148161

162+
func postAuthSAMLAuthSuccessButInvalidTokenURL(_ context.Context, _ *snowflakeRestful, _ map[string]string, _ []byte, _ time.Duration) (*authResponse, error) {
163+
return &authResponse{
164+
Success: true,
165+
Message: "",
166+
Data: authResponseMain{
167+
TokenURL: "invalid!@url$%^",
168+
SSOURL: "https://abc.com/sso",
169+
},
170+
}, nil
171+
}
172+
173+
func postAuthSAMLAuthSuccessButInvalidSSOURL(_ context.Context, _ *snowflakeRestful, _ map[string]string, _ []byte, _ time.Duration) (*authResponse, error) {
174+
return &authResponse{
175+
Success: true,
176+
Message: "",
177+
Data: authResponseMain{
178+
TokenURL: "https://abc.com/token",
179+
SSOURL: "invalid!@url$%^",
180+
},
181+
}, nil
182+
}
183+
149184
func postAuthSAMLAuthSuccess(_ context.Context, _ *snowflakeRestful, _ map[string]string, _ []byte, _ time.Duration) (*authResponse, error) {
150185
return &authResponse{
151186
Success: true,
@@ -177,6 +212,10 @@ func getSSOSuccess(_ context.Context, _ *snowflakeRestful, _ *url.Values, _ map[
177212
return []byte(`<html><form id="1" action="https&#x3a;&#x2f;&#x2f;abc.com&#x2f;"></form></html>`), nil
178213
}
179214

215+
func getSSOSuccessButWrongPrefixURL(_ context.Context, _ *snowflakeRestful, _ *url.Values, _ map[string]string, _ string, _ time.Duration) ([]byte, error) {
216+
return []byte(`<html><form id="1" action="https&#x3a;&#x2f;&#x2f;1abc.com&#x2f;"></form></html>`), nil
217+
}
218+
180219
func TestUnitAuthenticateBySAML(t *testing.T) {
181220
authenticator := &url.URL{
182221
Scheme: "https",
@@ -195,46 +234,63 @@ func TestUnitAuthenticateBySAML(t *testing.T) {
195234
}
196235
var err error
197236
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
198-
if err == nil {
199-
t.Fatal("should have failed.")
200-
}
237+
assertNotNilF(t, err, "should have failed at FuncPostAuthSAML.")
238+
assertEqualE(t, err.Error(), "failed to get SAML response")
239+
201240
sr.FuncPostAuthSAML = postAuthSAMLAuthFail
202241
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
203-
if err == nil {
204-
t.Fatal("should have failed.")
205-
}
206-
sr.FuncPostAuthSAML = postAuthSAMLAuthSuccessButInvalidURL
242+
assertNotNilF(t, err, "should have failed at FuncPostAuthSAML.")
243+
assertEqualE(t, err.Error(), "strconv.Atoi: parsing \"\": invalid syntax")
244+
245+
sr.FuncPostAuthSAML = postAuthSAMLAuthFailWithCode
207246
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
208-
if err == nil {
209-
t.Fatal("should have failed.")
210-
}
247+
assertNotNilF(t, err, "should have failed at FuncPostAuthSAML.")
211248
driverErr, ok := err.(*SnowflakeError)
212-
if !ok {
213-
t.Fatalf("should be snowflake error. err: %v", err)
214-
}
215-
if driverErr.Number != ErrCodeIdpConnectionError {
216-
t.Fatalf("unexpected error code. expected: %v, got: %v", ErrCodeIdpConnectionError, driverErr.Number)
217-
}
249+
assertTrueF(t, ok, "should be a SnowflakeError")
250+
assertEqualE(t, driverErr.Number, ErrCodeIdpConnectionError)
251+
252+
sr.FuncPostAuthSAML = postAuthSAMLAuthSuccessButInvalidURL
253+
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
254+
assertNotNilF(t, err, "should have failed at FuncPostAuthSAML.")
255+
driverErr, ok = err.(*SnowflakeError)
256+
assertTrueF(t, ok, "should be a SnowflakeError")
257+
assertEqualE(t, driverErr.Number, ErrCodeIdpConnectionError)
258+
259+
sr.FuncPostAuthSAML = postAuthSAMLAuthSuccessButInvalidTokenURL
260+
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
261+
assertNotNilF(t, err, "should have failed at FuncPostAuthSAML.")
262+
assertEqualE(t, err.Error(), "failed to parse token URL. invalid!@url$%^")
263+
264+
sr.FuncPostAuthSAML = postAuthSAMLAuthSuccessButInvalidSSOURL
265+
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
266+
assertNotNilF(t, err, "should have failed at FuncPostAuthSAML.")
267+
assertEqualE(t, err.Error(), "failed to parse SSO URL. invalid!@url$%^")
268+
218269
sr.FuncPostAuthSAML = postAuthSAMLAuthSuccess
219270
sr.FuncPostAuthOKTA = postAuthOKTAError
220271
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
221-
if err == nil {
222-
t.Fatal("should have failed.")
223-
}
272+
assertNotNilF(t, err, "should have failed at FuncPostAuthOKTA.")
273+
assertEqualE(t, err.Error(), "failed to get SAML response")
274+
224275
sr.FuncPostAuthOKTA = postAuthOKTASuccess
225276
sr.FuncGetSSO = getSSOError
226277
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
227-
if err == nil {
228-
t.Fatal("should have failed.")
229-
}
278+
assertNotNilF(t, err, "should have failed at FuncGetSSO.")
279+
assertEqualE(t, err.Error(), "failed to get SSO html")
280+
230281
sr.FuncGetSSO = getSSOSuccessButInvalidURL
231282
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
232-
if err == nil {
233-
t.Fatal("should have failed.")
234-
}
283+
assertNotNilF(t, err, "should have failed at FuncGetSSO.")
284+
assertHasPrefixE(t, err.Error(), "failed to find action field in HTML response")
285+
235286
sr.FuncGetSSO = getSSOSuccess
236287
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
237-
if err != nil {
238-
t.Fatalf("failed. err: %v", err)
239-
}
288+
assertNilF(t, err, "should have succeeded at FuncGetSSO.")
289+
290+
sr.FuncGetSSO = getSSOSuccessButWrongPrefixURL
291+
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
292+
assertNotNilF(t, err, "should have failed at FuncGetSSO.")
293+
driverErr, ok = err.(*SnowflakeError)
294+
assertTrueF(t, ok, "should be a SnowflakeError")
295+
assertEqualE(t, driverErr.Number, ErrCodeSSOURLNotMatch)
240296
}

connector_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,23 @@ func TestConnector(t *testing.T) {
4747
t.Fatalf("Missing driver")
4848
}
4949
}
50+
51+
func TestConnectorWithMissingConfig(t *testing.T) {
52+
conn := snowflakeConn{}
53+
mock := noopTestDriver{conn: &conn}
54+
config := Config{
55+
User: "u",
56+
Password: "p",
57+
Account: "",
58+
}
59+
expectedErr := errEmptyAccount()
60+
61+
connector := NewConnector(&mock, config)
62+
_, err := connector.Connect(context.Background())
63+
assertNotNilF(t, err, "the connection should have failed due to empty account.")
64+
65+
driverErr, ok := err.(*SnowflakeError)
66+
assertTrueF(t, ok, "should be a SnowflakeError")
67+
assertEqualE(t, driverErr.Number, expectedErr.Number)
68+
assertEqualE(t, driverErr.Message, expectedErr.Message)
69+
}

converter_test.go

+64
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,70 @@ func TestArrowToValue(t *testing.T) {
538538
},
539539
higherPrecision: true,
540540
},
541+
{
542+
logical: "fixed",
543+
physical: "int16",
544+
values: []string{"1.2345", "2.3456"},
545+
rowType: execResponseRowType{Scale: 4},
546+
builder: array.NewInt16Builder(pool),
547+
append: func(b array.Builder, vs interface{}) {
548+
for _, s := range vs.([]string) {
549+
num, ok := stringFloatToInt(s, 4)
550+
if !ok {
551+
t.Fatalf("failed to convert to int")
552+
}
553+
b.(*array.Int16Builder).Append(int16(num))
554+
}
555+
},
556+
compare: func(src interface{}, dst []snowflakeValue) int {
557+
srcvs := src.([]string)
558+
for i := range srcvs {
559+
num, ok := stringFloatToInt(srcvs[i], 4)
560+
if !ok {
561+
return i
562+
}
563+
srcDec := intToBigFloat(num, 4)
564+
dstDec := dst[i].(*big.Float)
565+
if srcDec.Cmp(dstDec) != 0 {
566+
return i
567+
}
568+
}
569+
return -1
570+
},
571+
higherPrecision: true,
572+
},
573+
{
574+
logical: "fixed",
575+
physical: "int16",
576+
values: []string{"1.2345", "2.3456"},
577+
rowType: execResponseRowType{Scale: 4},
578+
builder: array.NewInt16Builder(pool),
579+
append: func(b array.Builder, vs interface{}) {
580+
for _, s := range vs.([]string) {
581+
num, ok := stringFloatToInt(s, 4)
582+
if !ok {
583+
t.Fatalf("failed to convert to int")
584+
}
585+
b.(*array.Int16Builder).Append(int16(num))
586+
}
587+
},
588+
compare: func(src interface{}, dst []snowflakeValue) int {
589+
srcvs := src.([]string)
590+
for i := range srcvs {
591+
num, ok := stringFloatToInt(srcvs[i], 4)
592+
if !ok {
593+
return i
594+
}
595+
srcDec := fmt.Sprintf("%.*f", 4, float64(num)/math.Pow10(int(4)))
596+
dstDec := dst[i]
597+
if srcDec != dstDec {
598+
return i
599+
}
600+
}
601+
return -1
602+
},
603+
higherPrecision: false,
604+
},
541605
{
542606
logical: "fixed",
543607
physical: "int32",

dsn_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,10 @@ func TestParseDSN(t *testing.T) {
706706
ocspMode: ocspModeFailOpen,
707707
err: nil,
708708
},
709+
{
710+
dsn: "u:[email protected]:443?authenticator=http%3A%2F%2Fsc.okta.com&ocspFailOpen=true&validateDefaultParameters=true",
711+
err: errFailedToParseAuthenticator(),
712+
},
709713
}
710714

711715
for _, at := range []AuthType{AuthTypeExternalBrowser, AuthTypeOAuth} {

errors.go

+8
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,14 @@ func errInvalidRegion() *SnowflakeError {
327327
}
328328
}
329329

330+
// Returned if a DSN includes an invalid authenticator.
331+
func errFailedToParseAuthenticator() *SnowflakeError {
332+
return &SnowflakeError{
333+
Number: ErrCodeFailedToParseAuthenticator,
334+
Message: "failed to parse an authenticator",
335+
}
336+
}
337+
330338
// Returned if the server side returns an error without meaningful message.
331339
func errUnknownError() *SnowflakeError {
332340
return &SnowflakeError{

0 commit comments

Comments
 (0)