Added test coverage for crash recovery
diff --git a/buffering_manager_test.go b/buffering_manager_test.go
index 5378604..fa4ad85 100644
--- a/buffering_manager_test.go
+++ b/buffering_manager_test.go
@@ -96,6 +96,9 @@
 			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")))
+
+			err = os.Remove(completeFilePath)
+			Expect(err).ToNot((HaveOccurred()))
 		})
 	})
 })
diff --git a/crash_recovery_test.go b/crash_recovery_test.go
new file mode 100644
index 0000000..68bb5e6
--- /dev/null
+++ b/crash_recovery_test.go
@@ -0,0 +1,166 @@
+package apidAnalytics
+
+import (
+	"compress/gzip"
+	"encoding/json"
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+var _ = Describe("test crashRecoveryNeeded(), ", func() {
+	Context("directories in recovered folder", func() {
+		It("should return true", func() {
+			dirName := "t~e~20160108536000~recoveredTS~20160101222612.123"
+			dirPath := filepath.Join(localAnalyticsRecoveredDir, dirName)
+
+			err := os.Mkdir(dirPath, os.ModePerm)
+			Expect(err).ShouldNot(HaveOccurred())
+
+			needed := crashRecoveryNeeded()
+			Expect(needed).To(BeTrue())
+
+			err = os.Remove(dirPath)
+			Expect(err).ShouldNot(HaveOccurred())
+		})
+	})
+	Context("directories in tmp folder", func() {
+		It("should return true", func() {
+			d := "t~e~20160112630000"
+			dirPath := filepath.Join(localAnalyticsTempDir, d)
+			fp := filepath.Join(dirPath, "fakefile.txt.gz")
+			err := os.Mkdir(dirPath, os.ModePerm)
+			Expect(err).ShouldNot(HaveOccurred())
+
+			_, err = os.Create(fp)
+			Expect(err).ShouldNot(HaveOccurred())
+
+			needed := crashRecoveryNeeded()
+			Expect(needed).To(BeTrue())
+
+			// moves file to recovered dir
+			dirs, _ := ioutil.ReadDir(localAnalyticsRecoveredDir)
+			for _, dir := range dirs {
+				if strings.Contains(dir.Name(), d) {
+					Expect(dir.Name()).To(
+						ContainSubstring(d + recoveredTS))
+					err = os.RemoveAll(localAnalyticsRecoveredDir +
+						"/" + dir.Name())
+					Expect(err).ShouldNot(HaveOccurred())
+				}
+			}
+		})
+	})
+})
+
+var _ = Describe("test performRecovery(), ", func() {
+	It("should move all recovered directories to staging", func() {
+		dirName := "t~e~20160101545000~recoveredTS~20160101222612.123"
+		dirPath := filepath.Join(localAnalyticsRecoveredDir, dirName)
+		err := os.Mkdir(dirPath, os.ModePerm)
+		Expect(err).ShouldNot(HaveOccurred())
+
+		performRecovery()
+		newPath := filepath.Join(localAnalyticsStagingDir, dirName)
+		Expect(newPath).To(BeADirectory())
+
+		err = os.Remove(newPath)
+		Expect(err).ShouldNot(HaveOccurred())
+	})
+})
+
+var _ = Describe("test recoverDirectory(), ", func() {
+	It("should recover file and move folder to staging", func() {
+		dirName := "t~e~20160101535000~recoveredTS~20160101222612.123"
+		dirPath := filepath.Join(localAnalyticsRecoveredDir, dirName)
+		fp := filepath.Join(dirPath, "fakefile.txt.gz")
+		err := os.Mkdir(dirPath, os.ModePerm)
+		Expect(err).ShouldNot(HaveOccurred())
+
+		recoveredFile, err := os.OpenFile(fp,
+			os.O_WRONLY|os.O_CREATE, os.ModePerm)
+		Expect(err).ShouldNot(HaveOccurred())
+
+		gw := gzip.NewWriter(recoveredFile)
+
+		// write some content to file
+		var records = []byte(`{
+					"response_status_code": 200,
+					"client_id":"testapikey",
+					"client_received_start_timestamp": 1486406248277,
+					"client_received_end_timestamp": 1486406248290
+				}`)
+		gw.Write(records)
+		gw.Close()
+		recoveredFile.Close()
+
+		recoverDirectory(dirName)
+
+		stagingPath := filepath.Join(localAnalyticsStagingDir, dirName)
+		Expect(dirPath).ToNot(BeADirectory())
+		Expect(stagingPath).To(BeADirectory())
+
+		err = os.RemoveAll(stagingPath)
+		Expect(err).ShouldNot(HaveOccurred())
+	})
+})
+
+var _ = Describe("test recoverFile(), ", func() {
+	It("should create a recovered file and delete parital file", func() {
+		dirName := "t~e~20160101530000~recoveredTS~20160101222612.123"
+		dirPath := filepath.Join(localAnalyticsRecoveredDir, dirName)
+		fp := filepath.Join(dirPath, "fakefile.txt.gz")
+		err := os.Mkdir(dirPath, os.ModePerm)
+		Expect(err).ShouldNot(HaveOccurred())
+
+		recoveredFile, err := os.OpenFile(fp,
+			os.O_WRONLY|os.O_CREATE, os.ModePerm)
+		Expect(err).ShouldNot(HaveOccurred())
+
+		gw := gzip.NewWriter(recoveredFile)
+
+		// write some content to file
+		var records = []byte(`{
+					"response_status_code": 200,
+					"client_id":"testapikey",
+					"client_received_start_timestamp": 1486406248277,
+					"client_received_end_timestamp": 1486406248290
+				}`)
+		gw.Write(records)
+		gw.Close()
+		recoveredFile.Close()
+
+		recoverFile("_20160101222612.123", dirName, "fakefile.txt.gz")
+
+		recoveredFileName := "fakefile_recovered_20160101222612.123.txt.gz"
+		recoveredFilePath := filepath.Join(dirPath, recoveredFileName)
+		Expect(recoveredFilePath).To(BeAnExistingFile())
+		Expect(fp).ToNot(BeAnExistingFile())
+
+		// Verify file was written to properly
+		f, err := os.Open(recoveredFilePath)
+		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")))
+
+		err = os.RemoveAll(dirPath)
+		Expect(err).ShouldNot(HaveOccurred())
+	})
+})