From 0e5cdebd69660113a3418678d458067d8243e36d Mon Sep 17 00:00:00 2001 From: porosnicuadrian Date: Thu, 3 Dec 2020 17:50:27 +0200 Subject: [PATCH] Integration and unit tests for utils+splitted some functions for coverage --- utils/coreutils.go | 77 +++++++++------- utils/coreutils_it_test.go | 140 +++++++++++++++++++++++++++++ utils/coreutils_test.go | 10 +++ utils/stir_shaken_utils_it_test.go | 38 ++++++-- 4 files changed, 227 insertions(+), 38 deletions(-) create mode 100644 utils/coreutils_it_test.go diff --git a/utils/coreutils.go b/utils/coreutils.go index 6f68a4538..c05d73dda 100644 --- a/utils/coreutils.go +++ b/utils/coreutils.go @@ -216,12 +216,7 @@ func ParseTimeDetectLayout(tmStr string, timezone string) (time.Time, error) { case tmStr == "*monthly": return time.Now().AddDate(0, 1, 0), nil // add one month case tmStr == "*monthly_estimated": - initialMnt := time.Now().Month() - tAfter := time.Now().AddDate(0, 1, 0) - for tAfter.Month()-initialMnt > 1 { - tAfter = tAfter.AddDate(0, 0, -1) - } - return tAfter, nil + return monthlyEstimated(time.Now()) case tmStr == "*yearly": return time.Now().AddDate(1, 0, 0), nil // add one year @@ -296,6 +291,15 @@ func ParseTimeDetectLayout(tmStr string, timezone string) (time.Time, error) { return nilTime, errors.New("Unsupported time format") } +func monthlyEstimated(t1 time.Time) (time.Time, error) { + initialMnt := t1.Month() + tAfter := t1.AddDate(0, 1, 0) + for tAfter.Month()-initialMnt > 1 { + tAfter = tAfter.AddDate(0, 0, -1) + } + return tAfter, nil +} + // RoundDuration returns a number equal or larger than the amount that exactly // is divisible to whole func RoundDuration(whole, amount time.Duration) time.Duration { @@ -403,41 +407,56 @@ func InfieldSplit(val string) []string { return strings.Split(val, INFIELD_SEP) } +//Splited Unzip in small functions to have better coverage func Unzip(src, dest string) error { r, err := zip.OpenReader(src) if err != nil { return err } defer r.Close() - for _, f := range r.File { - rc, err := f.Open() - if err != nil { - return err - } - defer rc.Close() - path := filepath.Join(dest, f.Name) if f.FileInfo().IsDir() { os.MkdirAll(path, f.Mode()) - } else { - f, err := os.OpenFile( - path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) - if err != nil { - return err - } - defer f.Close() - - _, err = io.Copy(f, rc) - if err != nil { - return err - } + continue + } + err = unzipFile(f, path, f.Mode()) + if err != nil { + return err } } + return err +} +type zipFile interface { + Open() (io.ReadCloser, error) +} + +func unzipFile(f zipFile, path string, fm os.FileMode) (err error) { + rc, err := f.Open() + if err != nil { + return err + } + err = copyFile(rc, path, fm) + rc.Close() + if err != nil { + return err + } return nil } +func copyFile(rc io.ReadCloser, path string, fm os.FileMode) (err error) { + f, err := os.OpenFile( + path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, fm) + if err != nil { + return err + } + defer f.Close() + + _, err = io.Copy(f, rc) + return +} + // successive Fibonacci numbers. func Fib() func() int { a, b := 0, 1 @@ -957,12 +976,10 @@ func AESDecrypt(encrypted string, encKey string) (txt string, err error) { // Hash generates the hash text func ComputeHash(dataKeys ...string) (lns string, err error) { var hashByts []byte - if hashByts, err = bcrypt.GenerateFromPassword( + hashByts, err = bcrypt.GenerateFromPassword( []byte(ConcatenatedKey(dataKeys...)), - bcrypt.MinCost); err != nil { - return - } - return string(hashByts), nil + bcrypt.MinCost) + return string(hashByts), err } // VerifyHash matches the data hash with the dataKeys ha diff --git a/utils/coreutils_it_test.go b/utils/coreutils_it_test.go new file mode 100644 index 000000000..643fdcef7 --- /dev/null +++ b/utils/coreutils_it_test.go @@ -0,0 +1,140 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package utils + +import ( + "archive/zip" + "fmt" + "io" + "os" + "path" + "testing" +) + +var ( + tests = []func(t *testing.T){ + testLongExecTimeDetector, + testUnzip, + testUnzipADirectory, + testUnzipOpenFileError, + } +) + +func TestCoreUtilsIT(t *testing.T) { + for _, tests := range tests { + t.Run("Core_utils", tests) + } +} + +func testLongExecTimeDetector(t *testing.T) { + if rcv := LongExecTimeDetector("RandomMessage", -1); cap(rcv) != 1 { + t.Errorf("Expected %+v, received %+v", 1, cap(rcv)) + } +} + +func testUnzip(t *testing.T) { + flPath := "/tmp/testUnzip" + if err := os.MkdirAll(flPath, 0777); err != nil { + t.Error(err) + } + newFile, err := os.Create(path.Join(flPath, "random.zip")) + if err != nil { + t.Error(err) + } + + expectedErr := "zip: not a valid zip file" + if err := Unzip(path.Join(flPath, "random.zip"), EmptyString); err == nil || err.Error() != expectedErr { + t.Errorf("Expected %+v, received %+v", expectedErr, err) + } + + w := zip.NewWriter(newFile) + for _, file := range []string{"file.txt"} { + f, err := w.Create(file) + if err != nil { + t.Error(err) + } + f.Write([]byte("noMessage")) + } + + w.Close() + + newFile.Close() + + expectedErr = "open /tmp/randomMessage/file.txt: no such file or directory" + if err := Unzip(path.Join(flPath, "random.zip"), "/tmp/randomMessage"); err == nil || err.Error() != expectedErr { + t.Errorf("Expected %+v, received %+v", expectedErr, err) + } + + if err = os.Remove(path.Join(flPath, "random.zip")); err != nil { + t.Fatal(err) + } + + if err = os.RemoveAll(flPath); err != nil { + t.Fatal(err) + } +} + +func testUnzipADirectory(t *testing.T) { + flPath := "/tmp/testUnzip" + if err := os.MkdirAll(flPath, 0777); err != nil { + t.Error(err) + } + newFile, err := os.Create(path.Join(flPath, "random.zip")) + if err != nil { + t.Error(err) + } + + w := zip.NewWriter(newFile) + + for _, file := range []string{"file/", "file.txt"} { + f, err := w.Create(file) + if err != nil { + t.Error(err) + } + f.Write([]byte(`noMessage`)) + } + + w.Close() + + newFile.Close() + + if err := Unzip(path.Join(flPath, "random.zip"), flPath); err != nil { + t.Error(err) + } + if err = os.Remove(path.Join(flPath, "random.zip")); err != nil { + t.Fatal(err) + } + + if err = os.RemoveAll(flPath); err != nil { + t.Fatal(err) + } +} + +type zipFileTest struct{} + +func (zipFileTest) Open() (io.ReadCloser, error) { + return nil, fmt.Errorf("Cannot open the file") +} + +func testUnzipOpenFileError(t *testing.T) { + expectdErr := "Cannot open the file" + if err := unzipFile(new(zipFileTest), EmptyString, 0); err == nil || err.Error() != expectdErr { + t.Errorf("Expected %+v, received %+v", expectdErr, err) + } +} diff --git a/utils/coreutils_test.go b/utils/coreutils_test.go index 8bd1d91fc..04aa5e1c3 100644 --- a/utils/coreutils_test.go +++ b/utils/coreutils_test.go @@ -1600,3 +1600,13 @@ func TestBoolGenerator(t *testing.T) { t.Errorf("Needs to be bool") } } + +func TestMonthlyEstimated(t *testing.T) { + t1 := time.Date(2021, 1, 31, 0, 0, 0, 0, time.UTC) + expectedTime := time.Date(2021, 2, 28, 0, 0, 0, 0, time.UTC) + if rcv, err := monthlyEstimated(t1); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(rcv, expectedTime) { + t.Errorf("Expected %+v, received %+v", expectedTime, rcv) + } +} diff --git a/utils/stir_shaken_utils_it_test.go b/utils/stir_shaken_utils_it_test.go index 68130a647..bf3277ba6 100644 --- a/utils/stir_shaken_utils_it_test.go +++ b/utils/stir_shaken_utils_it_test.go @@ -19,8 +19,11 @@ along with this program. If not, see package utils import ( + "reflect" "testing" "time" + + "github.com/dgrijalva/jwt-go" ) var ( @@ -55,17 +58,36 @@ func testGetReaderFromPathStatusCode(t *testing.T) { } func testNewECDSAPrvKey(t *testing.T) { - urlPath := "https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm" - expPrvKey := "Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key" - if _, err := NewECDSAPrvKey(urlPath, time.Duration(0)); err == nil || err.Error() != expPrvKey { - t.Errorf("Expected %+v, received %+v", expPrvKey, err) + urlPath := "https://raw.githubusercontent.com/cgrates/cgrates/master/data/stir/stir_privatekey.pem" + expected, err := jwt.ParseECPrivateKeyFromPEM([]byte(` +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEICcL1+2nj9ylMlTKjSpIGx03gALK0cISciviwudQuvb9oAoGCCqGSM49 +AwEHoUQDQgAEjS4zmWotYqKWB2/sn+4v1uUoPAQ2N2ZtrUsmewkl3ErAbIokXSZS +rucJPPszlBtYbbhcmbXC7DKP9u9Pq/GnVg== +-----END EC PRIVATE KEY-----`)) + if err != nil { + t.Error(err) + } + if prvKey, err := NewECDSAPrvKey(urlPath, time.Duration(0)); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expected, prvKey) { + t.Errorf("Expected %+v, received %+v", expected, prvKey) } } func testNewECDSAPublicKey(t *testing.T) { - urlPath := "https://en.wikipedia.org/wiki/Wiki" - expPublKey := "Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key" - if _, err := NewECDSAPubKey(urlPath, 0); err == nil || err.Error() != expPublKey { - t.Errorf("Expected %+v, received %+v", expPublKey, err) + urlPath := "https://raw.githubusercontent.com/cgrates/cgrates/master/data/stir/stir_pubkey.pem" + expPublKey, err := jwt.ParseECPublicKeyFromPEM([]byte(` +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjS4zmWotYqKWB2/sn+4v1uUoPAQ2 +N2ZtrUsmewkl3ErAbIokXSZSrucJPPszlBtYbbhcmbXC7DKP9u9Pq/GnVg== +-----END PUBLIC KEY-----`)) + if err != nil { + t.Error(err) + } + if publKey, err := NewECDSAPubKey(urlPath, 0); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expPublKey, publKey) { + t.Errorf("Expected %+v, received %+v", expPublKey, publKey) } }