Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Storage Integration Testing #236

Merged
merged 36 commits into from
Jul 10, 2017
Merged

Add Storage Integration Testing #236

merged 36 commits into from
Jul 10, 2017

Conversation

mh-park
Copy link
Contributor

@mh-park mh-park commented Jun 28, 2017

w/ an example on ElasticSearch

@mh-park mh-park requested a review from black-adder June 28, 2017 15:30
"github.com/uber/jaeger/model"
)

type TraceByKey []*model.Trace
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you mean "by trace id"?


func compareModelTags(t *testing.T, expected []model.KeyValue, actual []model.KeyValue) {
sort.Sort(TagByKey(expected))
sort.Sort(TagByKey(actual))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this mean ES backend does not preserve the order of tags in the Span document?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ES does, but this is for any general backend.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair enough. I would suggest having a single "normalize" function that does all the sorting on a given trace, and after that ideally just use assert.Equal on the whole object. If you run into issues with pointers being slightly different, you can convert the whole thing to a JSON and do equals on strings.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the downside to doing that would be that it would be difficult to see where the traces differ.

Copy link
Member

@yurishkuro yurishkuro Jun 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not necessarily. First, you can use pretty to print the diffs, as done here. Another trick I used was to write out the JSON to files (when the test fails) so that they can be compared with other tools like diff.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just kidding, i think assert.EqualValues tells us where

// this function exists solely to make it easier for developer to find out where the difference is
func compareModelLogs(t *testing.T, expected []model.Log, actual []model.Log) {
sort.Sort(LogByTimestamp(expected))
sort.Sort(LogByTimestamp(actual))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same question - why doesn't the backend simply preserve the order of logs?


const (
byService QueryType = iota
bysNoN
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

bysNTags
bysNDuration
byNumOfTraces
// Add more queryTypes here
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need these enums instead of simply having distinct test cases as data or as test methods? Each scenario requires special data to be inserted into storage before querying.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're right. I think I used this earlier when I needed the enums, but i changed the format and we no longer need it. i'll refactor

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling d9ca512 on es-itest into 3c5b63c on master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 8a12bc7 on es-itest into 3c5b63c on master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling b854c66 on es-itest into 3c5b63c on master.

@mh-park
Copy link
Contributor Author

mh-park commented Jun 29, 2017

there might be unused stuff that i haven't caught, let me know if you find anything such

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling aa38aba on es-itest into 3c5b63c on master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling aa38aba on es-itest into 3c5b63c on master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling d4077b5 on es-itest into 3c5b63c on master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling eb14aad on es-itest into 3c5b63c on master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling eb14aad on es-itest into 3c5b63c on master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling fea22a5 on es-itest into 3c5b63c on master.

@black-adder
Copy link
Contributor

revert idl

func (s spanBySpanID) Less(i, j int) bool { return s[i].SpanID < s[j].SpanID }

// SortTraces checks two traces' length and sorts their spans.
func SortTraces(expected *Trace, actual *Trace) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was more thinking sort just one trace and leave the comparisons to domain_trace_compare_test.go

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, so I did this before, and the issue with this was that I would get index out of bound error with the assert.Equals, and the error message wouldn't be very helpful. the current way catches these because they'll do a length check on the way

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sort the traces separately but still do the length checks in domain_trace_compare_test.go?

return errors.New("elastic search is not ready")
}

// DO NOT RUN IF YOU HAVE IMPORTANT SPANS IN ELASTICSEARCH
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this comment still valid? hopefully people arent stupid enough to run integration tests in production

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

never trust people

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 25c106b on es-itest into 3c5b63c on master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling ed0a89d on es-itest into 3c5b63c on master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling b7a5877 on es-itest into 3c5b63c on master.

Copy link
Contributor

@black-adder black-adder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot one test case where we return more than one trace, tis the last one I swear

model/sort.go Outdated
func (s spanBySpanID) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s spanBySpanID) Less(i, j int) bool { return s[i].SpanID < s[j].SpanID }

// SortTrace checks two traces' length and sorts their spans.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update comment

"github.com/uber/jaeger/model"
)

type TraceByTraceID []*model.Trace
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not move this to model as well?

expectedSpan := expected.Spans[i]
actualSpan := actual.Spans[i]
require.True(t, len(expectedSpan.Tags) == len(actualSpan.Tags))
require.True(t, len(expectedSpan.Logs) == len(actualSpan.Logs))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compare process tag lengths

func (s *StorageIntegration) IntegrationTestGetServices(t *testing.T) {
t.Log("Testing GetServices ...")

// TODO
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

func (s *StorageIntegration) IntegrationTestGetOperations(t *testing.T) {
t.Log("Testing GetOperations ...")

// TODO
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

}

func (s *StorageIntegration) integrationTestFindTracesByQuery(t *testing.T, query *spanstore.TraceQueryParameters, expectedFixture string) {
expectedTrace, err := getTraceFixture(expectedFixture)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these 3 lines seem to be repeated in every test


var found bool
var actual []*model.Trace
for i := 0; i < 30; i++ {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const 30 to iterations or something

var found bool
var actual []*model.Trace
for i := 0; i < 30; i++ {
s.logger.Info(fmt.Sprintf("Waiting for storage backend to update documents, iteration %d out of %d", i+1, 30))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this comment repeated everywhere, DRY it

s.logger.Info(fmt.Sprintf("Waiting for storage backend to update documents, iteration %d out of %d", i+1, 30))
actual, err = s.reader.FindTraces(query)
if err == nil {
if len(actual) == query.NumTraces {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but NumTrace in your queries are always 1000, so this never gets hit

s.logger.Info(fmt.Sprintf("Waiting for storage backend to update documents, iteration %d out of %d", i+1, 30))
actual, err = s.reader.GetTrace(traceID)
if err == nil {
found = len(actual.Spans) == len(expected.Spans)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, this one you can inline

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling b1650b4 on es-itest into 3c5b63c on master.

Copy link
Contributor

@black-adder black-adder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't include multiple traces test yet?

model/sort.go Outdated
func (s traceByTraceID) Len() int { return len(s) }
func (s traceByTraceID) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s traceByTraceID) Less(i, j int) bool {
if len(s[i].Spans) != len(s[j].Spans) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

number of spans should have no bearing on the order of the traces unless the traceIDs are identical

t.Log("Testing GetTrace ...")

expected := s.getBasicFixture(t)
expectedTraceID := model.TraceID{Low: 17}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so you cant get this from expected instead of hard coding it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh thats what you meant ok i can do that

s.logger.Info(fmt.Sprintf(waitForBackendComment, i+1, iterations))
actual, err := s.reader.GetTrace(expectedTraceID)
if err == nil {
if found = len(actual.Spans) == len(expected.Spans); found {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need the found variable, you can just do the length check here and L148

s.logger.Info(fmt.Sprintf(waitForBackendComment, i+1, iterations))
actual, err = s.reader.FindTraces(query)
if err == nil {
if len(actual) == query.NumTraces {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so we dont need this right?

found = true
break
}
found = tracesMatch(actual, expected)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why can't we do:

if tracesMatch(actual, expected) {
     break
}

and then CompareSliceOfTraces below after the for loop once? Given CompareSliceOfTraces uses require will stop execution anyway for bad traces, just do it once

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling e7a97ec on es-itest into 3c5b63c on master.


func (s traceByTraceID) Len() int { return len(s) }
func (s traceByTraceID) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s traceByTraceID) Less(i, j int) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s[i].Spans[0].TraceID.Low < s[j].Spans[0].TraceID.Low is the only check you need now thinking about it. You can't (shouldn't) have two traces with the same id so using the traceid as the tie breaker is all you need.

s.logger.Info(fmt.Sprintf(waitForBackendComment, i+1, iterations))
var err error
actual, err = s.reader.GetTrace(expectedTraceID)
if err == nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can combine these two if stmts

expected, err := getTraceFixtures(expectedFixtures)
require.NoError(t, err)
require.NoError(t, s.writeTraces(expected))
require.NoError(t, s.refresh())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

require.NoError(t, s.refresh()) here but the other tests dont do require.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 61bcbad on es-itest into 3c5b63c on master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling ff11a78 on es-itest into 3c5b63c on master.

@mh-park mh-park merged commit 433b7e0 into master Jul 10, 2017
@mh-park mh-park deleted the es-itest branch July 17, 2017 15:25
ideepika pushed a commit to ideepika/jaeger that referenced this pull request Oct 22, 2017
* create integration test framework for storage + create elasticsearch integration test

* refactor queries format

* rename comparison fns to fit its behavior

* fix rand.Uint64() (does not exist in go1.7)

* revert env var check

* refactor trace w/ query checker to separate file + test

* import list reorder

* change itest direction

* change integration test format

* make fmt/lint

* make fmt/lint

* prettify output when test fails

* fmt

* delete query to trace checker

* remove unnecessary code

* add integration test script

* fix syntax

* add comment about fixtures and queries

* fix travis yml to run es integ test

* remove es integ test from install travis

* fix typo

* fix err check bug

* fmt

* move sorting fns to model

* fix imports

* fix code reviews

* change trace fixtures to describe the trace

* revert idl

* trust people

* sort refactored

* fix trace comparison test + raise timeout for es-integration test

* code review

* remove numtraces check

* add multiple-trace test case

* code review
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants