Skip to content

Commit

Permalink
SNOW-870356: Increase code coverage on CodeCov (#921)
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-ext-simba-jl authored Oct 30, 2023
1 parent ea57743 commit 1f9df02
Show file tree
Hide file tree
Showing 11 changed files with 373 additions and 45 deletions.
4 changes: 4 additions & 0 deletions assert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import (
"testing"
)

func assertNilE(t *testing.T, actual any, descriptions ...string) {
errorOnNonEmpty(t, validateNil(actual, descriptions...))
}

func assertNilF(t *testing.T, actual any, descriptions ...string) {
fatalOnNonEmpty(t, validateNil(actual, descriptions...))
}
Expand Down
30 changes: 30 additions & 0 deletions auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,36 @@ func TestUnitAuthenticateWithConfigMFA(t *testing.T) {
}
}

func TestUnitAuthenticateWithConfigOkta(t *testing.T) {
var err error
sr := &snowflakeRestful{
Protocol: "https",
Host: "abc.com",
Port: 443,
FuncPostAuthSAML: postAuthSAMLAuthSuccess,
FuncPostAuthOKTA: postAuthOKTASuccess,
FuncGetSSO: getSSOSuccess,
FuncPostAuth: postAuthSuccess,
TokenAccessor: getSimpleTokenAccessor(),
}
sc := getDefaultSnowflakeConn()
sc.cfg.Authenticator = AuthTypeOkta
sc.cfg.OktaURL = &url.URL{
Scheme: "https",
Host: "abc.com",
}
sc.rest = sr
sc.ctx = context.Background()

err = authenticateWithConfig(sc)
assertNilE(t, err, "expected to have no error.")

sr.FuncPostAuthSAML = postAuthSAMLError
err = authenticateWithConfig(sc)
assertNotNilF(t, err, "should have failed at FuncPostAuthSAML.")
assertEqualE(t, err.Error(), "failed to get SAML response")
}

func TestUnitAuthenticateExternalBrowser(t *testing.T) {
var err error
sr := &snowflakeRestful{
Expand Down
4 changes: 2 additions & 2 deletions authokta.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ func authenticateBySAML(
if tokenURL, err = url.Parse(respd.Data.TokenURL); err != nil {
return nil, fmt.Errorf("failed to parse token URL. %v", respd.Data.TokenURL)
}
if ssoURL, err = url.Parse(respd.Data.TokenURL); err != nil {
return nil, fmt.Errorf("failed to parse ssoURL URL. %v", respd.Data.SSOURL)
if ssoURL, err = url.Parse(respd.Data.SSOURL); err != nil {
return nil, fmt.Errorf("failed to parse SSO URL. %v", respd.Data.SSOURL)
}
if !isPrefixEqual(oktaURL, ssoURL) || !isPrefixEqual(oktaURL, tokenURL) {
return nil, &SnowflakeError{
Expand Down
112 changes: 84 additions & 28 deletions authokta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"net/http"
"net/url"
"strconv"
"testing"
"time"
)
Expand Down Expand Up @@ -122,6 +123,10 @@ func TestUnitGetSSO(t *testing.T) {
if err != nil {
t.Fatalf("failed to get HTML content. err: %v", err)
}
_, err = getSSO(context.Background(), sr, &url.Values{}, make(map[string]string), "invalid!@url$%^", 0)
if err == nil {
t.Fatal("should have failed to parse URL.")
}
}

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

func postAuthSAMLAuthFailWithCode(_ context.Context, _ *snowflakeRestful, _ map[string]string, _ []byte, _ time.Duration) (*authResponse, error) {
return &authResponse{
Success: false,
Code: strconv.Itoa(ErrCodeIdpConnectionError),
Message: "SAML auth failed",
}, nil
}

func postAuthSAMLAuthSuccessButInvalidURL(_ context.Context, _ *snowflakeRestful, _ map[string]string, _ []byte, _ time.Duration) (*authResponse, error) {
return &authResponse{
Success: true,
Expand All @@ -146,6 +159,28 @@ func postAuthSAMLAuthSuccessButInvalidURL(_ context.Context, _ *snowflakeRestful
}, nil
}

func postAuthSAMLAuthSuccessButInvalidTokenURL(_ context.Context, _ *snowflakeRestful, _ map[string]string, _ []byte, _ time.Duration) (*authResponse, error) {
return &authResponse{
Success: true,
Message: "",
Data: authResponseMain{
TokenURL: "invalid!@url$%^",
SSOURL: "https://abc.com/sso",
},
}, nil
}

func postAuthSAMLAuthSuccessButInvalidSSOURL(_ context.Context, _ *snowflakeRestful, _ map[string]string, _ []byte, _ time.Duration) (*authResponse, error) {
return &authResponse{
Success: true,
Message: "",
Data: authResponseMain{
TokenURL: "https://abc.com/token",
SSOURL: "invalid!@url$%^",
},
}, nil
}

func postAuthSAMLAuthSuccess(_ context.Context, _ *snowflakeRestful, _ map[string]string, _ []byte, _ time.Duration) (*authResponse, error) {
return &authResponse{
Success: true,
Expand Down Expand Up @@ -177,6 +212,10 @@ func getSSOSuccess(_ context.Context, _ *snowflakeRestful, _ *url.Values, _ map[
return []byte(`<html><form id="1" action="https&#x3a;&#x2f;&#x2f;abc.com&#x2f;"></form></html>`), nil
}

func getSSOSuccessButWrongPrefixURL(_ context.Context, _ *snowflakeRestful, _ *url.Values, _ map[string]string, _ string, _ time.Duration) ([]byte, error) {
return []byte(`<html><form id="1" action="https&#x3a;&#x2f;&#x2f;1abc.com&#x2f;"></form></html>`), nil
}

func TestUnitAuthenticateBySAML(t *testing.T) {
authenticator := &url.URL{
Scheme: "https",
Expand All @@ -195,46 +234,63 @@ func TestUnitAuthenticateBySAML(t *testing.T) {
}
var err error
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
if err == nil {
t.Fatal("should have failed.")
}
assertNotNilF(t, err, "should have failed at FuncPostAuthSAML.")
assertEqualE(t, err.Error(), "failed to get SAML response")

sr.FuncPostAuthSAML = postAuthSAMLAuthFail
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
if err == nil {
t.Fatal("should have failed.")
}
sr.FuncPostAuthSAML = postAuthSAMLAuthSuccessButInvalidURL
assertNotNilF(t, err, "should have failed at FuncPostAuthSAML.")
assertEqualE(t, err.Error(), "strconv.Atoi: parsing \"\": invalid syntax")

sr.FuncPostAuthSAML = postAuthSAMLAuthFailWithCode
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
if err == nil {
t.Fatal("should have failed.")
}
assertNotNilF(t, err, "should have failed at FuncPostAuthSAML.")
driverErr, ok := err.(*SnowflakeError)
if !ok {
t.Fatalf("should be snowflake error. err: %v", err)
}
if driverErr.Number != ErrCodeIdpConnectionError {
t.Fatalf("unexpected error code. expected: %v, got: %v", ErrCodeIdpConnectionError, driverErr.Number)
}
assertTrueF(t, ok, "should be a SnowflakeError")
assertEqualE(t, driverErr.Number, ErrCodeIdpConnectionError)

sr.FuncPostAuthSAML = postAuthSAMLAuthSuccessButInvalidURL
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
assertNotNilF(t, err, "should have failed at FuncPostAuthSAML.")
driverErr, ok = err.(*SnowflakeError)
assertTrueF(t, ok, "should be a SnowflakeError")
assertEqualE(t, driverErr.Number, ErrCodeIdpConnectionError)

sr.FuncPostAuthSAML = postAuthSAMLAuthSuccessButInvalidTokenURL
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
assertNotNilF(t, err, "should have failed at FuncPostAuthSAML.")
assertEqualE(t, err.Error(), "failed to parse token URL. invalid!@url$%^")

sr.FuncPostAuthSAML = postAuthSAMLAuthSuccessButInvalidSSOURL
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
assertNotNilF(t, err, "should have failed at FuncPostAuthSAML.")
assertEqualE(t, err.Error(), "failed to parse SSO URL. invalid!@url$%^")

sr.FuncPostAuthSAML = postAuthSAMLAuthSuccess
sr.FuncPostAuthOKTA = postAuthOKTAError
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
if err == nil {
t.Fatal("should have failed.")
}
assertNotNilF(t, err, "should have failed at FuncPostAuthOKTA.")
assertEqualE(t, err.Error(), "failed to get SAML response")

sr.FuncPostAuthOKTA = postAuthOKTASuccess
sr.FuncGetSSO = getSSOError
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
if err == nil {
t.Fatal("should have failed.")
}
assertNotNilF(t, err, "should have failed at FuncGetSSO.")
assertEqualE(t, err.Error(), "failed to get SSO html")

sr.FuncGetSSO = getSSOSuccessButInvalidURL
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
if err == nil {
t.Fatal("should have failed.")
}
assertNotNilF(t, err, "should have failed at FuncGetSSO.")
assertHasPrefixE(t, err.Error(), "failed to find action field in HTML response")

sr.FuncGetSSO = getSSOSuccess
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
if err != nil {
t.Fatalf("failed. err: %v", err)
}
assertNilF(t, err, "should have succeeded at FuncGetSSO.")

sr.FuncGetSSO = getSSOSuccessButWrongPrefixURL
_, err = authenticateBySAML(context.Background(), sr, authenticator, application, account, user, password)
assertNotNilF(t, err, "should have failed at FuncGetSSO.")
driverErr, ok = err.(*SnowflakeError)
assertTrueF(t, ok, "should be a SnowflakeError")
assertEqualE(t, driverErr.Number, ErrCodeSSOURLNotMatch)
}
20 changes: 20 additions & 0 deletions connector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,23 @@ func TestConnector(t *testing.T) {
t.Fatalf("Missing driver")
}
}

func TestConnectorWithMissingConfig(t *testing.T) {
conn := snowflakeConn{}
mock := noopTestDriver{conn: &conn}
config := Config{
User: "u",
Password: "p",
Account: "",
}
expectedErr := errEmptyAccount()

connector := NewConnector(&mock, config)
_, err := connector.Connect(context.Background())
assertNotNilF(t, err, "the connection should have failed due to empty account.")

driverErr, ok := err.(*SnowflakeError)
assertTrueF(t, ok, "should be a SnowflakeError")
assertEqualE(t, driverErr.Number, expectedErr.Number)
assertEqualE(t, driverErr.Message, expectedErr.Message)
}
64 changes: 64 additions & 0 deletions converter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,70 @@ func TestArrowToValue(t *testing.T) {
},
higherPrecision: true,
},
{
logical: "fixed",
physical: "int16",
values: []string{"1.2345", "2.3456"},
rowType: execResponseRowType{Scale: 4},
builder: array.NewInt16Builder(pool),
append: func(b array.Builder, vs interface{}) {
for _, s := range vs.([]string) {
num, ok := stringFloatToInt(s, 4)
if !ok {
t.Fatalf("failed to convert to int")
}
b.(*array.Int16Builder).Append(int16(num))
}
},
compare: func(src interface{}, dst []snowflakeValue) int {
srcvs := src.([]string)
for i := range srcvs {
num, ok := stringFloatToInt(srcvs[i], 4)
if !ok {
return i
}
srcDec := intToBigFloat(num, 4)
dstDec := dst[i].(*big.Float)
if srcDec.Cmp(dstDec) != 0 {
return i
}
}
return -1
},
higherPrecision: true,
},
{
logical: "fixed",
physical: "int16",
values: []string{"1.2345", "2.3456"},
rowType: execResponseRowType{Scale: 4},
builder: array.NewInt16Builder(pool),
append: func(b array.Builder, vs interface{}) {
for _, s := range vs.([]string) {
num, ok := stringFloatToInt(s, 4)
if !ok {
t.Fatalf("failed to convert to int")
}
b.(*array.Int16Builder).Append(int16(num))
}
},
compare: func(src interface{}, dst []snowflakeValue) int {
srcvs := src.([]string)
for i := range srcvs {
num, ok := stringFloatToInt(srcvs[i], 4)
if !ok {
return i
}
srcDec := fmt.Sprintf("%.*f", 4, float64(num)/math.Pow10(int(4)))
dstDec := dst[i]
if srcDec != dstDec {
return i
}
}
return -1
},
higherPrecision: false,
},
{
logical: "fixed",
physical: "int32",
Expand Down
4 changes: 4 additions & 0 deletions dsn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,10 @@ func TestParseDSN(t *testing.T) {
ocspMode: ocspModeFailOpen,
err: nil,
},
{
dsn: "u:[email protected]:443?authenticator=http%3A%2F%2Fsc.okta.com&ocspFailOpen=true&validateDefaultParameters=true",
err: errFailedToParseAuthenticator(),
},
}

for _, at := range []AuthType{AuthTypeExternalBrowser, AuthTypeOAuth} {
Expand Down
8 changes: 8 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,14 @@ func errInvalidRegion() *SnowflakeError {
}
}

// Returned if a DSN includes an invalid authenticator.
func errFailedToParseAuthenticator() *SnowflakeError {
return &SnowflakeError{
Number: ErrCodeFailedToParseAuthenticator,
Message: "failed to parse an authenticator",
}
}

// Returned if the server side returns an error without meaningful message.
func errUnknownError() *SnowflakeError {
return &SnowflakeError{
Expand Down
Loading

0 comments on commit 1f9df02

Please sign in to comment.