Merge pull request #3 from 30x/pooja_xapid_377_testcases
Added test coverage for helpers, api, listener, init and buffer manager
diff --git a/api_helper_test.go b/api_helper_test.go
new file mode 100644
index 0000000..2ccc9f5
--- /dev/null
+++ b/api_helper_test.go
@@ -0,0 +1,112 @@
+package apidAnalytics
+
+import (
+ "bytes"
+ "encoding/json"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+// BeforeSuite setup and AfterSuite cleanup is in apidAnalytics_suite_test.go
+var _ = Describe("test valid() directly", func() {
+ Context("invalid record", func() {
+ It("should return invalid record", func() {
+ By("payload with missing required keys")
+
+ var record = []byte(`{
+ "response_status_code": 200,
+ "client_id":"testapikey"
+ }`)
+ raw := getRaw(record)
+ valid, e := validate(raw)
+
+ Expect(valid).To(Equal(false))
+ Expect(e.ErrorCode).To(Equal("MISSING_FIELD"))
+
+ By("payload with clst > clet")
+ record = []byte(`{
+ "response_status_code": 200,
+ "client_id":"testapikey",
+ "client_received_start_timestamp": 1486406248277,
+ "client_received_end_timestamp": 1486406248260
+ }`)
+ raw = getRaw(record)
+ valid, e = validate(raw)
+
+ Expect(valid).To(Equal(false))
+ Expect(e.ErrorCode).To(Equal("BAD_DATA"))
+ Expect(e.Reason).To(Equal("client_received_start_timestamp > client_received_end_timestamp"))
+
+ })
+ })
+ Context("valid record", func() {
+ It("should return true", func() {
+ var record = []byte(`{
+ "response_status_code": 200,
+ "client_id":"testapikey",
+ "client_received_start_timestamp": 1486406248277,
+ "client_received_end_timestamp": 1486406248290
+ }`)
+ raw := getRaw(record)
+ valid, _ := validate(raw)
+ Expect(valid).To(Equal(true))
+ })
+ })
+})
+
+var _ = Describe("test enrich() directly", func() {
+ Context("enrich record for existing apiKey", func() {
+ It("developer related fields should be added", func() {
+ var record = []byte(`{
+ "response_status_code": 200,
+ "client_id":"testapikey",
+ "client_received_start_timestamp": 1486406248277,
+ "client_received_end_timestamp": 1486406248290
+ }`)
+
+ raw := getRaw(record)
+ tenant := tenant{Org: "testorg", Env: "testenv", TenantId: "tenantid"}
+ enrich(raw, "testid", tenant)
+
+ Expect(raw["organization"]).To(Equal(tenant.Org))
+ Expect(raw["environment"]).To(Equal(tenant.Env))
+ Expect(raw["api_product"]).To(Equal("testproduct"))
+ Expect(raw["developer_app"]).To(Equal("testapp"))
+ Expect(raw["developer_email"]).To(Equal("testdeveloper@test.com"))
+ Expect(raw["developer"]).To(Equal("testdeveloper"))
+ })
+ })
+
+ Context("enrich record where no apikey is set", func() {
+ It("developer related fields should not be added", func() {
+ var record = []byte(`{
+ "response_status_code": 200,
+ "client_received_start_timestamp": 1486406248277,
+ "client_received_end_timestamp": 1486406248290
+ }`)
+
+ raw := getRaw(record)
+ tenant := tenant{Org: "testorg", Env: "testenv", TenantId: "tenantid"}
+ enrich(raw, "testid", tenant)
+
+ Expect(raw["organization"]).To(Equal(tenant.Org))
+ Expect(raw["environment"]).To(Equal(tenant.Env))
+ Expect(raw["api_product"]).To(BeNil())
+ Expect(raw["developer_app"]).To(BeNil())
+ Expect(raw["developer_email"]).To(BeNil())
+ Expect(raw["developer"]).To(BeNil())
+ })
+ })
+})
+
+func getRaw(record []byte) map[string]interface{} {
+ var raw map[string]interface{}
+
+ decoder := json.NewDecoder(bytes.NewReader(record)) // Decode payload to JSON data
+ decoder.UseNumber()
+ err := decoder.Decode(&raw)
+
+ Expect(err).ShouldNot(HaveOccurred())
+ return raw
+}
diff --git a/api_test.go b/api_test.go
index d172a29..83ce5a2 100644
--- a/api_test.go
+++ b/api_test.go
@@ -1,49 +1,203 @@
package apidAnalytics
import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
"net/http"
"net/url"
- "strings"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
// BeforeSuite setup and AfterSuite cleanup is in apidAnalytics_suite_test.go
-var _ = Describe("testing saveAnalyticsRecord() directly", func() {
- Context("valid scopeuuid", func() {
- It("should successfully return", func() {
+var _ = Describe("POST /analytics/{scopeuuid}", func() {
+ Context("invalid content type header", func() {
+ It("should return bad request", func() {
uri, err := url.Parse(testServer.URL)
- uri.Path = analyticsBasePath
-
- v := url.Values{}
- v.Add("bundle_scope_uuid", "testid")
-
- client := &http.Client{}
- req, err := http.NewRequest("POST", uri.String(),
- strings.NewReader(v.Encode()))
- res, err := client.Do(req)
- defer res.Body.Close()
+ uri.Path = fmt.Sprintf(analyticsBasePath+"/%s", "test")
Expect(err).ShouldNot(HaveOccurred())
- Expect(res.StatusCode, http.StatusOK)
+
+ req, _ := http.NewRequest("POST", uri.String(), nil)
+ req.Header.Set("Content-Type", "application/x-gzip")
+
+ res, e := makeRequest(req)
+
+ Expect(res.StatusCode).To(Equal(http.StatusBadRequest))
+ Expect(e.ErrorCode).To(Equal("UNSUPPORTED_CONTENT_TYPE"))
+ })
+ })
+
+ Context("invalid content encoding header", func() {
+ It("should return bad request", func() {
+ uri, err := url.Parse(testServer.URL)
+ uri.Path = fmt.Sprintf(analyticsBasePath+"/%s", "testid")
+ Expect(err).ShouldNot(HaveOccurred())
+
+ req, _ := http.NewRequest("POST", uri.String(), nil)
+ req.Header.Set("Content-Type", "application/json")
+ req.Header.Set("Content-Encoding", "application/gzip")
+
+ res, e := makeRequest(req)
+
+ Expect(res.StatusCode).To(Equal(http.StatusBadRequest))
+ Expect(e.ErrorCode).To(Equal("UNSUPPORTED_CONTENT_ENCODING"))
})
})
Context("invalid scopeuuid", func() {
It("should return bad request", func() {
uri, err := url.Parse(testServer.URL)
- uri.Path = analyticsBasePath
-
- v := url.Values{}
- v.Add("bundle_scope_uuid", "wrongId")
-
- client := &http.Client{}
- req, err := http.NewRequest("POST", uri.String(),
- strings.NewReader(v.Encode()))
- res, err := client.Do(req)
- defer res.Body.Close()
+ uri.Path = fmt.Sprintf(analyticsBasePath+"/%s", "wrongid")
Expect(err).ShouldNot(HaveOccurred())
- Expect(res.StatusCode, http.StatusBadRequest)
+
+ req, _ := http.NewRequest("POST", uri.String(), nil)
+ req.Header.Set("Content-Type", "application/json")
+
+ res, e := makeRequest(req)
+
+ Expect(res.StatusCode).To(Equal(http.StatusBadRequest))
+ Expect(e.ErrorCode).To(Equal("UNKNOWN_SCOPE"))
+ })
+ })
+
+ Context("Unitialized DB", func() {
+ It("should return internal server error", func() {
+ db := getDB()
+ setDB(nil)
+
+ uri, err := url.Parse(testServer.URL)
+ uri.Path = fmt.Sprintf(analyticsBasePath+"/%s", "testid")
+ Expect(err).ShouldNot(HaveOccurred())
+
+ req, _ := http.NewRequest("POST", uri.String(), nil)
+ req.Header.Set("Content-Type", "application/json")
+
+ res, e := makeRequest(req)
+
+ Expect(res.StatusCode).To(Equal(http.StatusInternalServerError))
+ Expect(e.ErrorCode).To(Equal("INTERNAL_SERVER_ERROR"))
+
+ setDB(db)
+
+ })
+ })
+
+ Context("bad payload", func() {
+ It("should return bad request", func() {
+
+ By("no payload")
+ uri, err := url.Parse(testServer.URL)
+ uri.Path = fmt.Sprintf(analyticsBasePath+"/%s", "testid")
+ Expect(err).ShouldNot(HaveOccurred())
+
+ req, _ := http.NewRequest("POST", uri.String(), nil)
+ req.Header.Set("Content-Type", "application/json")
+
+ res, e := makeRequest(req)
+
+ Expect(res.StatusCode).To(Equal(http.StatusBadRequest))
+ Expect(e.ErrorCode).To(Equal("BAD_DATA"))
+ Expect(e.Reason).To(Equal("Not a valid JSON payload"))
+
+ By("payload with 0 records")
+ uri, err = url.Parse(testServer.URL)
+ uri.Path = fmt.Sprintf(analyticsBasePath+"/%s", "testid")
+ Expect(err).ShouldNot(HaveOccurred())
+
+ var payload = []byte(`{}`)
+ req, _ = http.NewRequest("POST", uri.String(), bytes.NewReader(payload))
+ req.Header.Set("Content-Type", "application/json")
+
+ res, e = makeRequest(req)
+
+ Expect(res.StatusCode).To(Equal(http.StatusBadRequest))
+ Expect(e.ErrorCode).To(Equal("NO_RECORDS"))
+
+ By("set content encoding to gzip but send json data")
+ uri, err = url.Parse(testServer.URL)
+ uri.Path = fmt.Sprintf(analyticsBasePath+"/%s", "testid")
+ Expect(err).ShouldNot(HaveOccurred())
+
+ payload = []byte(`{
+ "records":[{
+ "response_status_code": 200,
+ "client_id":"testapikey"
+ }]
+ }`)
+
+ req, _ = http.NewRequest("POST", uri.String(), bytes.NewReader(payload))
+ req.Header.Set("Content-Type", "application/json")
+ req.Header.Set("Content-Encoding", "gzip")
+
+ res, e = makeRequest(req)
+
+ Expect(res.StatusCode).To(Equal(http.StatusBadRequest))
+ Expect(e.ErrorCode).To(Equal("BAD_DATA"))
+ Expect(e.Reason).To(Equal("Gzip Encoded data cannot be read"))
+
+ By("1 bad record")
+ uri, err = url.Parse(testServer.URL)
+ uri.Path = fmt.Sprintf(analyticsBasePath+"/%s", "testid")
+ Expect(err).ShouldNot(HaveOccurred())
+
+ payload = []byte(`{
+ "records":[{
+ "response_status_code": 200,
+ "client_id":"testapikey",
+ "client_received_start_timestamp": 1486406248277,
+ "client_received_end_timestamp": 1486406248290
+ },{
+ "response_status_code": 200,
+ "client_id":"testapikey"
+ }]
+ }`)
+
+ req, _ = http.NewRequest("POST", uri.String(), bytes.NewReader(payload))
+ req.Header.Set("Content-Type", "application/json")
+
+ res, e = makeRequest(req)
+
+ Expect(res.StatusCode).To(Equal(http.StatusBadRequest))
+ Expect(e.ErrorCode).To(Equal("MISSING_FIELD"))
+ })
+ })
+
+ Context("valid payload", func() {
+ It("should return successfully", func() {
+ uri, err := url.Parse(testServer.URL)
+ uri.Path = fmt.Sprintf(analyticsBasePath+"/%s", "testid")
+ Expect(err).ShouldNot(HaveOccurred())
+
+ var payload = []byte(`{
+ "records":[{
+ "response_status_code": 200,
+ "client_id":"testapikey",
+ "client_received_start_timestamp": 1486406248277,
+ "client_received_end_timestamp": 1486406248290
+ }]
+ }`)
+
+ req, _ := http.NewRequest("POST", uri.String(), bytes.NewReader(payload))
+ req.Header.Set("Content-Type", "application/json")
+
+ res, _ := makeRequest(req)
+
+ Expect(res.StatusCode).To(Equal(http.StatusOK))
})
})
})
+
+func makeRequest(req *http.Request) (*http.Response, errResponse) {
+ res, err := client.Do(req)
+ defer res.Body.Close()
+ Expect(err).ShouldNot(HaveOccurred())
+
+ var body errResponse
+ respBody, _ := ioutil.ReadAll(res.Body)
+ json.Unmarshal(respBody, &body)
+
+ return res, body
+}
diff --git a/apidAnalytics_suite_test.go b/apidAnalytics_suite_test.go
index 1e5c128..345b4b8 100644
--- a/apidAnalytics_suite_test.go
+++ b/apidAnalytics_suite_test.go
@@ -26,36 +26,42 @@
var _ = BeforeSuite(func() {
apid.Initialize(factory.DefaultServicesFactory())
- config := apid.Config()
+ config = apid.Config()
var err error
testTempDir, err = ioutil.TempDir("", "api_test")
Expect(err).NotTo(HaveOccurred())
+ config.Set("local_storage_path", testTempDir)
config.Set("data_path", testTempDir)
- config.Set(uapServerBase, "http://localhost:9000") // dummy value
- config.Set("apigeesync_apid_instance_id",
- "abcdefgh-ijkl-mnop-qrst-uvwxyz123456") // dummy value
- config.Set(useCaching, true)
+ config.Set("apigeesync_apid_instance_id", "abcdefgh-ijkl-mnop-qrst-uvwxyz123456") // dummy value
db, err := apid.Data().DB()
Expect(err).NotTo(HaveOccurred())
- setDB(db)
+
createApidClusterTables(db)
createTables(db)
insertTestData(db)
- apid.InitializePlugins()
+ setDB(db)
- // Create cache else its created in listener.go when a snapshot is received
+ // required config uapServerBase is not set, thus init should panic
+ Expect(apid.InitializePlugins).To(Panic())
+
+ config.Set(uapServerBase, "http://localhost:9000") // dummy value
+ Expect(apid.InitializePlugins).ToNot(Panic())
+
+ config.Set(useCaching, true)
createTenantCache()
- createDeveloperInfoCache()
+ Expect(len(tenantCache)).To(Equal(1))
- testServer = httptest.NewServer(http.HandlerFunc(
- func(w http.ResponseWriter, req *http.Request) {
- if req.URL.Path == analyticsBasePathDefault {
- saveAnalyticsRecord(w, req)
- }
- }))
+ createDeveloperInfoCache()
+ Expect(len(developerInfoCache)).To(Equal(1))
+
+ router := apid.API().Router()
+ router.HandleFunc(analyticsBasePath+"/{bundle_scope_uuid}", func(w http.ResponseWriter, req *http.Request) {
+ saveAnalyticsRecord(w, req)
+ }).Methods("POST")
+ testServer = httptest.NewServer(router)
})
func createTables(db apid.DB) {
diff --git a/buffering_manager_test.go b/buffering_manager_test.go
new file mode 100644
index 0000000..1789317
--- /dev/null
+++ b/buffering_manager_test.go
@@ -0,0 +1,144 @@
+package apidAnalytics
+
+import (
+ "compress/gzip"
+ "encoding/json"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ "os"
+ "path/filepath"
+ "time"
+)
+
+var _ = Describe("test getBucketForTimestamp()", func() {
+ It("should return new bucket or existing bucket if created previously", func() {
+ t := time.Date(2017, 1, 20, 10, 24, 5, 0, time.Local)
+ tenant := tenant{Org: "testorg", Env: "testenv", TenantId: "tenantid"}
+
+ bucket, err := getBucketForTimestamp(t, tenant)
+ Expect(err).ShouldNot(HaveOccurred())
+
+ Expect(bucket.DirName).To(Equal("testorg~testenv~20170120102400"))
+ Expect(bucket.FileWriter).ToNot(BeNil())
+
+ fw := bucket.FileWriter
+ Expect(fw.file.Name()).To(ContainSubstring("20170120102400.20170120102600"))
+
+ // Should return existing bucket if same interval timestamp is passed
+ t2 := time.Date(2017, 1, 20, 10, 25, 5, 0, time.Local)
+ bucket, err = getBucketForTimestamp(t2, tenant)
+ Expect(err).ShouldNot(HaveOccurred())
+ Expect(bucket.DirName).To(Equal("testorg~testenv~20170120102400"))
+ })
+})
+
+var _ = Describe("test getRandomHex()", func() {
+ It("should return a 4 digit hex", func() {
+ r1 := getRandomHex()
+ Expect(len(r1)).To(Equal(4))
+ })
+
+ It("should return differe 4 digit hex each time", func() {
+ r1 := getRandomHex()
+ r2 := getRandomHex()
+
+ Expect(r1).NotTo(Equal(r2))
+ })
+})
+
+var _ = Describe("test createWriteAndCloseFile()", func() {
+ Context("Cannot create file", func() {
+ It("should return error", func() {
+ fileName := "testFile" + fileExtension
+ completeFilePath := filepath.Join(localAnalyticsTempDir, "fakedir", fileName)
+
+ _, err := createGzipFile(completeFilePath)
+ Expect(err).To((HaveOccurred()))
+ })
+
+ })
+ Context("Create file, write to it and close file", func() {
+ It("should save content to file and read correctly", func() {
+ fileName := "testFile" + fileExtension
+ completeFilePath := filepath.Join(localAnalyticsTempDir, fileName)
+
+ fw, err := createGzipFile(completeFilePath)
+ Expect(err).ToNot((HaveOccurred()))
+
+ var records = []byte(`{
+ "records":[{
+ "response_status_code": 200,
+ "client_id":"testapikey",
+ "client_received_start_timestamp": 1486406248277,
+ "client_received_end_timestamp": 1486406248290
+ }]
+ }`)
+
+ raw := getRaw(records)
+
+ writeGzipFile(fw, raw["records"].([]interface{}))
+ closeGzipFile(fw)
+
+ // Verify file was written to properly
+ f, err := os.Open(completeFilePath)
+ defer f.Close()
+ gzReader, err := gzip.NewReader(f)
+ defer gzReader.Close()
+ Expect(err).ToNot((HaveOccurred()))
+
+ var record map[string]interface{}
+ decoder := json.NewDecoder(gzReader) // Decode payload to JSON data
+ decoder.UseNumber()
+ err = decoder.Decode(&record)
+ Expect(err).ToNot((HaveOccurred()))
+
+ Expect(record["client_id"]).To(Equal("testapikey"))
+ Expect(record["response_status_code"]).To(Equal(json.Number("200")))
+ Expect(record["client_received_start_timestamp"]).To(Equal(json.Number("1486406248277")))
+ Expect(record["client_received_end_timestamp"]).To(Equal(json.Number("1486406248290")))
+ })
+ })
+})
+
+var _ = Describe("test closeBucketChannel()", func() {
+ Context("send close bucket event on channel", func() {
+ It("close file and move to staging dir", func() {
+ dirName := "testorg~testenv~20160101230000"
+ dirPath := filepath.Join(localAnalyticsTempDir, dirName)
+
+ err := os.Mkdir(dirPath, os.ModePerm)
+ Expect(err).ShouldNot(HaveOccurred())
+
+ fileName := "testFile" + fileExtension
+ completeFilePath := filepath.Join(dirPath, fileName)
+
+ fw, e := createGzipFile(completeFilePath)
+ Expect(e).ShouldNot(HaveOccurred())
+
+ bucket := bucket{DirName: dirName, FileWriter: fw}
+ closeBucketEvent <- bucket
+
+ // wait for it to close dir and move to staging
+ time.Sleep(time.Second * 2)
+
+ expectedDirPath := filepath.Join(localAnalyticsStagingDir, dirName)
+ status, _ := exists(expectedDirPath)
+ Expect(status).To(BeTrue())
+
+ expectedfilePath := filepath.Join(localAnalyticsStagingDir, dirName, fileName)
+ status, _ = exists(expectedfilePath)
+ Expect(status).To(BeTrue())
+ })
+ })
+})
+
+func exists(path string) (bool, error) {
+ _, err := os.Stat(path)
+ if err == nil {
+ return true, nil
+ }
+ if os.IsNotExist(err) {
+ return false, nil
+ }
+ return true, err
+}
diff --git a/common_helper_test.go b/common_helper_test.go
index c691d52..31bdb31 100644
--- a/common_helper_test.go
+++ b/common_helper_test.go
@@ -1,48 +1,109 @@
package apidAnalytics
import (
+ "database/sql"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("test getTenantForScope()", func() {
- Context("get tenant for valid scopeuuid", func() {
- It("should return testorg and testenv", func() {
- tenant, dbError := getTenantForScope("testid")
- Expect(dbError.Reason).To(Equal(""))
- Expect(tenant.Org).To(Equal("testorg"))
- Expect(tenant.Env).To(Equal("testenv"))
- Expect(tenant.TenantId).To(Equal("tenantid"))
+ Context("with usecaching set to true", func() {
+ Context("get tenant for valid scopeuuid", func() {
+ It("should return testorg and testenv", func() {
+ tenant, dbError := getTenantForScope("testid")
+ Expect(dbError.Reason).To(Equal(""))
+ Expect(tenant.TenantId).To(Equal("tenantid"))
+ })
+ })
+
+ Context("get tenant for invalid scopeuuid", func() {
+ It("should return empty tenant and a db error", func() {
+ tenant, dbError := getTenantForScope("wrongid")
+ Expect(tenant.Org).To(Equal(""))
+ Expect(dbError.ErrorCode).To(Equal("UNKNOWN_SCOPE"))
+ })
})
})
- Context("get tenant for invalid scopeuuid", func() {
- It("should return empty tenant and a db error", func() {
- tenant, dbError := getTenantForScope("wrongid")
- Expect(tenant.Org).To(Equal(""))
- Expect(dbError.ErrorCode).To(Equal("UNKNOWN_SCOPE"))
+ Context("with usecaching set to false", func() {
+ BeforeEach(func() {
+ config.Set(useCaching, false)
+ })
+ AfterEach(func() {
+ config.Set(useCaching, true)
+ })
+ Context("get tenant for valid scopeuuid", func() {
+ It("should return testorg and testenv", func() {
+ tenant, dbError := getTenantForScope("testid")
+ Expect(dbError.Reason).To(Equal(""))
+ Expect(tenant.Org).To(Equal("testorg"))
+ })
+ })
+
+ Context("get tenant for invalid scopeuuid", func() {
+ It("should return empty tenant and a db error", func() {
+ tenant, dbError := getTenantForScope("wrongid")
+ Expect(tenant.Org).To(Equal(""))
+ Expect(dbError.ErrorCode).To(Equal("UNKNOWN_SCOPE"))
+ })
})
})
})
var _ = Describe("test getDeveloperInfo()", func() {
- Context("get developerInfo for valid tenantId and apikey", func() {
- It("should return all right data", func() {
- developerInfo := getDeveloperInfo("tenantid", "testapikey")
- Expect(developerInfo.ApiProduct).To(Equal("testproduct"))
- Expect(developerInfo.Developer).To(Equal("testdeveloper"))
- Expect(developerInfo.DeveloperEmail).To(Equal("testdeveloper@test.com"))
- Expect(developerInfo.DeveloperApp).To(Equal("testapp"))
+ Context("with usecaching set to true", func() {
+ Context("get developerInfo for valid tenantId and apikey", func() {
+ It("should return all right data", func() {
+ developerInfo := getDeveloperInfo("tenantid", "testapikey")
+ Expect(developerInfo.ApiProduct).To(Equal("testproduct"))
+ Expect(developerInfo.Developer).To(Equal("testdeveloper"))
+ })
+ })
+
+ Context("get developerInfo for invalid tenantId and apikey", func() {
+ It("should return all right data", func() {
+ developerInfo := getDeveloperInfo("wrongid", "wrongapikey")
+ Expect(developerInfo.ApiProduct).To(Equal(""))
+ })
})
})
- Context("get developerInfo for invalid tenantId and apikey", func() {
- It("should return all right data", func() {
- developerInfo := getDeveloperInfo("wrongid", "wrongapikey")
- Expect(developerInfo.ApiProduct).To(Equal(""))
- Expect(developerInfo.Developer).To(Equal(""))
- Expect(developerInfo.DeveloperEmail).To(Equal(""))
- Expect(developerInfo.DeveloperApp).To(Equal(""))
+ Context("with usecaching set to false", func() {
+ BeforeEach(func() {
+ config.Set(useCaching, false)
+ })
+ AfterEach(func() {
+ config.Set(useCaching, true)
+ })
+ Context("get developerInfo for valid tenantId and apikey", func() {
+ It("should return all right data", func() {
+ developerInfo := getDeveloperInfo("tenantid", "testapikey")
+ Expect(developerInfo.ApiProduct).To(Equal("testproduct"))
+ Expect(developerInfo.Developer).To(Equal("testdeveloper"))
+ })
+ })
+ Context("get developerInfo for invalid tenantId and apikey", func() {
+ It("should return all right data", func() {
+ developerInfo := getDeveloperInfo("wrongid", "wrongapikey")
+ Expect(developerInfo.ApiProduct).To(Equal(""))
+ })
+ })
+ })
+})
+
+var _ = Describe("test getValuesIgnoringNull()", func() {
+ Context("Null sql value", func() {
+ It("should return empty string", func() {
+ a := sql.NullString{String: "null", Valid: false}
+ res := getValuesIgnoringNull(a)
+ Expect(res).To(Equal(""))
+ })
+ })
+ Context("not null sql value", func() {
+ It("should return string", func() {
+ a := sql.NullString{String: "sql", Valid: true}
+ res := getValuesIgnoringNull(a)
+ Expect(res).To(Equal("sql"))
})
})
})
diff --git a/init_test.go b/init_test.go
new file mode 100644
index 0000000..4c3649d
--- /dev/null
+++ b/init_test.go
@@ -0,0 +1,28 @@
+package apidAnalytics
+
+import (
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ "path/filepath"
+)
+
+var _ = Describe("test createDirectories()", func() {
+ Context("Parent directory exists", func() {
+ It("should create sub directory", func() {
+ subDir := filepath.Join(config.GetString("data_path"), "subDir")
+ directories := []string{subDir}
+
+ err := createDirectories(directories)
+ Expect(err).NotTo(HaveOccurred())
+ })
+ })
+ Context("Parent directory does not exists", func() {
+ subDir := filepath.Join("/fakepath", "subDir")
+ directories := []string{subDir}
+
+ It("sub directory creation should fail", func() {
+ err := createDirectories(directories)
+ Expect(err).To(HaveOccurred())
+ })
+ })
+})
diff --git a/listener_test.go b/listener_test.go
new file mode 100644
index 0000000..b792133
--- /dev/null
+++ b/listener_test.go
@@ -0,0 +1,140 @@
+package apidAnalytics
+
+import (
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "github.com/apigee-labs/transicator/common"
+)
+
+const (
+ LISTENER_TABLE_APP_CRED_MAPPER = "kms.app_credential_apiproduct_mapper"
+ LISTENER_TABLE_DATA_SCOPE = "edgex.data_scope"
+)
+
+var _ = Describe("listener", func() {
+ Context("Process changeList", func() {
+ Context(LISTENER_TABLE_DATA_SCOPE, func() {
+ It("insert/delete event should add/remove to/from cache if usecaching is true", func() {
+ config.Set(useCaching, true)
+ txn, err := getDB().Begin()
+ Expect(err).ShouldNot(HaveOccurred())
+ txn.Exec("INSERT INTO DATA_SCOPE (id, _change_selector, apid_cluster_id, scope, org, env) "+
+ "VALUES"+
+ "($1,$2,$3,$4,$5,$6)",
+ "i2",
+ "c2",
+ "a2",
+ "s2",
+ "o2",
+ "e2",
+ )
+ txn.Commit()
+
+ insert := common.ChangeList{
+ LastSequence: "test",
+ Changes: []common.Change{
+ {
+ Operation: common.Insert,
+ Table: LISTENER_TABLE_DATA_SCOPE,
+ NewRow: common.Row{
+ "id": &common.ColumnVal{Value: "i2"},
+ "_change_selector": &common.ColumnVal{Value: "c2"},
+ "apid_cluster_id": &common.ColumnVal{Value: "a2"},
+ "scope": &common.ColumnVal{Value: "s2"},
+ "org": &common.ColumnVal{Value: "o2"},
+ "env": &common.ColumnVal{Value: "e2"},
+ "created": &common.ColumnVal{Value: "c2"},
+ "created_by": &common.ColumnVal{Value: "c2"},
+ "updated": &common.ColumnVal{Value: "u2"},
+ "updated_by": &common.ColumnVal{Value: "u2"},
+ },
+ },
+ },
+ }
+
+ processChange(&insert)
+ tenant := tenantCache["i2"]
+ Expect(tenant.TenantId).To(Equal("s2"))
+ Expect(tenant.Org).To(Equal("o2"))
+ Expect(tenant.Env).To(Equal("e2"))
+
+ txn, err = getDB().Begin()
+ Expect(err).ShouldNot(HaveOccurred())
+ txn.Exec("DELETE FROM DATA_SCOPE where id = 'i2'")
+ txn.Commit()
+
+ delete := common.ChangeList{
+ LastSequence: "test",
+ Changes: []common.Change{
+ {
+ Operation: common.Delete,
+ Table: LISTENER_TABLE_DATA_SCOPE,
+ OldRow: insert.Changes[0].NewRow,
+ },
+ },
+ }
+
+ processChange(&delete)
+ _, exists := tenantCache["i2"]
+ Expect(exists).To(Equal(false))
+
+ })
+ })
+ Context(LISTENER_TABLE_APP_CRED_MAPPER, func() {
+ It("insert/delete event should refresh developer cache if usecaching is true", func() {
+ config.Set(useCaching, true)
+
+ txn, err := getDB().Begin()
+ Expect(err).ShouldNot(HaveOccurred())
+ txn.Exec("INSERT INTO APP_CREDENTIAL_APIPRODUCT_MAPPER (tenant_id, appcred_id, app_id, apiprdt_id, status, _change_selector) "+
+ "VALUES"+
+ "($1,$2,$3,$4,$5,$6)",
+ "tenantid",
+ "aci",
+ "ai",
+ "testproductid",
+ "APPROVED",
+ "12345",
+ )
+
+ txn.Exec("INSERT INTO APP (id, tenant_id, name, developer_id) "+
+ "VALUES"+
+ "($1,$2,$3,$4)",
+ "ai",
+ "tenantid",
+ "name",
+ "testdeveloperid",
+ )
+ txn.Commit()
+
+ insert := common.ChangeList{
+ LastSequence: "test",
+ Changes: []common.Change{
+ {
+ Operation: common.Insert,
+ Table: LISTENER_TABLE_APP_CRED_MAPPER,
+ NewRow: common.Row{
+ "tenant_id": &common.ColumnVal{Value: "tenantid"},
+ "appcred_id": &common.ColumnVal{Value: "aci"},
+ "app_id": &common.ColumnVal{Value: "ai"},
+ "apiprdt_id": &common.ColumnVal{Value: "api"},
+ "status": &common.ColumnVal{Value: "s"},
+ "_change_selector": &common.ColumnVal{Value: "c"},
+ },
+ },
+ },
+ }
+
+ processChange(&insert)
+ key := getKeyForDeveloperInfoCache("tenantid", "aci")
+ developerInfo := developerInfoCache[key]
+
+ Expect(developerInfo.ApiProduct).To(Equal("testproduct"))
+ Expect(developerInfo.Developer).To(Equal("testdeveloper"))
+ Expect(developerInfo.DeveloperEmail).To(Equal("testdeveloper@test.com"))
+ Expect(developerInfo.DeveloperApp).To(Equal("name"))
+ })
+ })
+ })
+})