Exemple #1
0
func TestInsert(t *testing.T) {
	var tests = []struct {
		symbol string
		span   stock.Span
	}{
		{"GOOG", testSpan1},
	}

	// create test db connection
	tdb := stock.DB.Setup(stock.TestLocal)

	// record the changes we make so they can be reversed, all measures in span will be inserted
	td := testhelpers.TearDown{}
	for _, test := range tests {
		td = td.TrackSpanInsert(test.symbol, &test.span, tdb, t)
	}
	defer func() {
		err := td.TearDown(tdb, t)
		if err != nil {
			t.Error(err)
		}
	}()

	for _, test := range tests {
		// do the DB.Insert()
		err := tdb.Insert(stock.NewStock(test.symbol), &test.span)
		if err != nil {
			t.Error(err)
		}

		// query for all data for test.symbol and compare against provided span
		// use a direct Queryx here, we'll test GetRange separately
		rows, err := tdb.Queryx(`SELECT Time, Value FROM Measures where Symbol = $1`, test.symbol)
		if err != nil {
			t.Error(err)
		}

		spanToCheck := *new(stock.Span)
		for rows.Next() {
			m := new(stock.Measure)
			err = rows.StructScan(m)
			if err != nil {
				t.Error(err)
			}
			spanToCheck = append(spanToCheck, *m)
		}

		// compare retrieved and expected spans
		if !test.span.Equal(spanToCheck) {
			t.Errorf("Error on DB.Insert(), database did not respond with expected number of results after insert -\nexpected:\n%+v\ngot:\n%+v\n", test.span, spanToCheck)
		}
	}

}
Exemple #2
0
// test getting data after DB.Insert(), same as above but we use the GetRange()
// method where we talked directly to the database before
func TestGetRange(t *testing.T) {
	var tests = []struct {
		symbol string
		span   stock.Span
	}{
		{"GOOG", testSpan1},
	}

	// create test db connection
	tdb := stock.DB.Setup(stock.TestLocal)

	// record the changes we make so they can be reversed, all measures in span will be inserted
	td := testhelpers.TearDown{}
	for _, test := range tests {
		td = td.TrackSpanInsert(test.symbol, &test.span, tdb, t)
	}
	defer func() {
		err := td.TearDown(tdb, t)
		if err != nil {
			t.Error(err)
		}
	}()

	for _, test := range tests {
		s := stock.NewStock(test.symbol)

		// do the DB.Insert()
		err := tdb.Insert(s, &test.span)
		if err != nil {
			t.Error(err)
		}

		// now get the range we just inserted
		sort.Sort(testSpan1)
		startDate := testSpan1[0].Time
		endDate := testSpan1[len(testSpan1)-1].Time
		span, err := tdb.GetRange(s, startDate, endDate)
		if err != nil {
			t.Error(err)
		}

		// compare retrieved and expected spans
		if !test.span.Equal(span) {
			t.Errorf("Error on DB.GetRange(), database did not respond with expected number of results after insert -\nexpected:\n%+v\ngot:\n%+v\n", test.span, span)
		}
	}
}
Exemple #3
0
// Confirm that DB.Setup completes with a functioning db and tables to populate
func TestSetup(t *testing.T) {
	var tests = []struct {
		table string // the name for each table that should be created in Setup
	}{
		{"measures"},
	}

	// test that a new db can be created, panics if fails
	tdb := stock.DB.Setup(stock.TestLocal)

	// record the changes we make so they can be reversed
	td := testhelpers.TearDown{}
	for _, test := range tests {
		td = append(td, (testhelpers.Change{Table: test.table, Action: testhelpers.CREATE}))
	}
	defer func() {
		err := td.TearDown(tdb, t)
		if err != nil {
			t.Error(err)
		}
	}()

	// and ensure it has all the tables that we expect
	for _, test := range tests {
		testQuery := strings.Join([]string{"SELECT * FROM ", test.table}, "")
		rows, err := tdb.Query(testQuery)
		if err != nil {
			// if the table does not exist we'll get an error
			t.Error(err)
		} else {
			// we'll get rows if the table exists, but won't be able to access any data
			hasNext := rows.Next()
			if hasNext {
				// if we have data something is wrong
				t.Errorf("Expected empty table but got results with query `%s`", testQuery)
			}
		}
	}

}
Exemple #4
0
func TestGetStockIntegration(t *testing.T) {
	// start a new server so we can access it's ServeHTTP method
	trueVal := true
	ts := NewTrendyServer(Flags{Local: &trueVal})

	// test has db impact, setup test db
	tdb := stock.DB.Setup(stock.TestLocal)

	// run default test set for Markit
	testdata := testhelpers.MarkitTestData
	for _, test := range testdata {
		// .../stock/<test.Sym>?start=<test.StartDate>&end=<test.EndDate>, dates as YYYY-MM-DD
		path := strings.Join([]string{`/stock/`, test.Sym, `?start=`, test.StartDate.Format("2006-01-02"), `&end=`, test.EndDate.Format("2006-01-02")}, "")
		t.Logf("path: `%s`\n", path)

		// first try without auth parameters, this should be rejected
		r, _ := http.NewRequest("GET", path, nil)
		w := httptest.NewRecorder()
		ts.ServeHTTP(w, r)

		b := w.Body.String()
		if w.Code != http.StatusUnauthorized || !strings.Contains(b, "No Key Or Secret") {
			t.Errorf("Attempted access without key/secret succeeded. Invalid access granted.\n>> Status:%d for %s", w.Code, path)
		}

		// try request again with key and secret set correctly
		r, _ = http.NewRequest("GET", path, nil)
		r.Header.Set("X-Auth-Key", "key")
		r.Header.Set("X-Auth-Secret", "secret")
		w = httptest.NewRecorder()
		ts.ServeHTTP(w, r)

		if !test.ExpectError {
			// expect success
			if w.Code != http.StatusOK {
				t.Errorf("Attempted access with key/secret but failed, expected success.\n>> Status:%d for %s", w.Code, path)
			}

			// record the changes we make so they can be reversed, all measures in span will be inserted
			td := testhelpers.TearDown{}
			expectedSpan := test.ExpectedMarkitResponse.GetSpan()
			td = td.TrackSpanInsert(test.Sym, &expectedSpan, tdb, t)

			expectedStock := stock.NewStock(test.Sym)
			expectedStock.Span = expectedSpan
			expectedJson, err := json.Marshal(expectedStock)
			if err != nil {
				t.Errorf("Error generating JSON response for expected stock [%s]", test.Sym)
			}
			expectedStr := strings.Replace(string(expectedJson), "T12:", "T00:", -1) // expectation is at T12, returned at T00, this is a quick hacky fix

			if b = w.Body.String(); b != expectedStr {
				t.Errorf("(%d) Got unexpected response from server, expected:\n%s\ngot:\n%s\n", w.Code, expectedJson, b)
			}

			// teardown changes
			err = td.TearDown(tdb, t)
			if err != nil {
				t.Error(err)
			}

		} else {
			// expect error
			if w.Code == http.StatusOK {
				t.Errorf("Attempted access expecting failure but got success.\n>> Status:%d for %s", w.Code, path)
			}
		}
	}
}
Exemple #5
0
func TestRangeIntegration(t *testing.T) {
	// test has db impact, setup test db
	tdb := stock.DB.Setup(stock.TestLocal)

	// run default test set for Markit
	testdata := testhelpers.MarkitTestData
	for _, test := range testdata {
		s := stock.NewStock(test.Sym)

		// initialize a request to get the URL so that we can inform the test server
		// of the target url, this request is not used otherwise.
		unusedRequest, err := stock.NewMarkitChartAPIRequest(s, test.StartDate, test.EndDate)
		if err != nil {
			t.Errorf("Could not create a MarkitChartAPIRequest: %v", err)
		}
		targetUrl := unusedRequest.Url // save the targetUrl for the request

		// start test server with success status
		tsParams := testhelpers.TestServer{
			Status: http.StatusOK, RequestUrl: targetUrl, TestData: testdata, T: t,
		}
		ts := httptest.NewServer(&tsParams)

		// make sure database and memory are empty for stock
		checkMemoryAndDatabase(s, &stock.Span{}, tdb, t)

		// test five most common error responses
		var errorCodes = []int{500, 404, 403, 400, 401}
		for _, errorCode := range errorCodes {
			tsParams = testhelpers.TestServer{
				Status: errorCode, RequestUrl: targetUrl, TestData: testdata, T: t,
			}

			span, err := s.ActualRange(test.StartDate, test.EndDate, ts.URL)
			if err == nil || len(span) > 0 {
				t.Errorf("Expected an error but got success: %+v\n", span)
			}
		}

		// make sure database and memory are still empty
		checkMemoryAndDatabase(s, &stock.Span{}, tdb, t)

		// change server to success status
		tsParams = testhelpers.TestServer{
			Status: http.StatusOK, RequestUrl: targetUrl, TestData: testdata, T: t,
		}

		// get the span here
		span, err := s.ActualRange(test.StartDate, test.EndDate, ts.URL)
		if test.ExpectError {
			if err == nil {
				t.Errorf("Expected error but got success")
			} else {
				// checkMemoryAndDatabase are empty and then continue, no teardown
				checkMemoryAndDatabase(s, &stock.Span{}, tdb, t)
				t.Logf("Test complete: %s, %s to %s", test.Sym, test.StartDate.String(), test.EndDate.String())
				continue
			}
		} else if err != nil {
			t.Error(err)
		}

		// record the changes we make so they can be reversed, all measures in span will be inserted
		td := testhelpers.TearDown{}
		td = td.TrackSpanInsert(s.Symbol, &span, tdb, t)

		// ensure that the returned span equals the expected
		expectedSpan := test.ExpectedMarkitResponse.GetSpan()
		if !span.Equal(expectedSpan) {
			t.Errorf("Error - stock.Range() did not return expected span\nexpected:\n%+v\ngot:\n%+v\n", expectedSpan, span)
		}

		// make sure database and memory also reflect the expected
		checkMemoryAndDatabase(s, &expectedSpan, tdb, t)

		// teardown changes (not deferred because we want to do for each loop - not sure that's necessary though)
		err = td.TearDown(tdb, t)
		if err != nil {
			t.Error(err)
		}

		t.Logf("Test complete: %s, %s to %s", test.Sym, test.StartDate.String(), test.EndDate.String())
	}
}