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)
}
}