Skip to content

Commit

Permalink
Add transform test for query plan (#630)
Browse files Browse the repository at this point in the history
* Add transform test for query plan

* Cover all combinations of reference switches
  • Loading branch information
keiko713 authored Nov 13, 2024
1 parent c8032bb commit 903fc2c
Showing 1 changed file with 151 additions and 48 deletions.
199 changes: 151 additions & 48 deletions output/transform/transform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/binary"
"encoding/json"
"testing"
"time"

"github.com/pganalyze/collector/output/pganalyze_collector"
"github.com/pganalyze/collector/output/transform"
Expand All @@ -15,10 +16,14 @@ import (
func TestStatements(t *testing.T) {
key1 := state.PostgresStatementKey{QueryID: 1}
key2 := state.PostgresStatementKey{QueryID: 2}
pKey1 := state.PostgresPlanKey{PlanID: 111}
pKey2 := state.PostgresPlanKey{PlanID: 222}
pKey1.QueryID = key2.QueryID
pKey2.QueryID = key2.QueryID

newState := state.PersistedState{}
transientState := state.TransientState{Statements: make(state.PostgresStatementMap), StatementTexts: make(state.PostgresStatementTextMap)}
diffState := state.DiffState{StatementStats: make(state.DiffedPostgresStatementStatsMap)}
transientState := state.TransientState{Statements: make(state.PostgresStatementMap), StatementTexts: make(state.PostgresStatementTextMap), Plans: make(state.PostgresPlanMap)}
diffState := state.DiffState{StatementStats: make(state.DiffedPostgresStatementStatsMap), PlanStats: make(state.DiffedPostgresPlanStatsMap)}

q1 := "SELECT 1"
q2 := "SELECT * FROM test"
Expand All @@ -28,16 +33,22 @@ func TestStatements(t *testing.T) {
fp2 := util.FingerprintQuery(q2, "none", -1)
fpBuf2 := make([]byte, 8)
binary.BigEndian.PutUint64(fpBuf2, fp2)
capturedTime := time.Time{}
transientState.Statements[key1] = state.PostgresStatement{Fingerprint: fp1}
transientState.Statements[key2] = state.PostgresStatement{Fingerprint: fp2}
transientState.StatementTexts[fp1] = q1
transientState.StatementTexts[fp2] = q2
transientState.Plans[pKey1] = state.PostgresPlan{ExplainPlan: "Index Scan", PlanCapturedTime: capturedTime}
transientState.Plans[pKey2] = state.PostgresPlan{ExplainPlan: "Bitmap Heap Scan", PlanCapturedTime: capturedTime}
diffState.StatementStats[key1] = state.DiffedPostgresStatementStats{Calls: 1}
diffState.StatementStats[key2] = state.DiffedPostgresStatementStats{Calls: 13}
diffState.PlanStats[pKey1] = state.DiffedPostgresStatementStats{Calls: 2}
diffState.PlanStats[pKey2] = state.DiffedPostgresStatementStats{Calls: 24}

actual := transform.StateToSnapshot(newState, diffState, transientState)
actualJSON, _ := json.Marshal(actual)

// Query: 0, 1, Plan: 0, 1
expected := pganalyze_collector.FullSnapshot{
Config: &pganalyze_collector.CollectorConfig{},
CollectorStatistic: &pganalyze_collector.CollectorStatistic{},
Expand Down Expand Up @@ -88,64 +99,156 @@ func TestStatements(t *testing.T) {
Calls: 13,
},
},
}
expectedJSON, _ := json.Marshal(expected)

// Sadly this is the quickest way with all the idx references...
expectedAlt := pganalyze_collector.FullSnapshot{
Config: &pganalyze_collector.CollectorConfig{},
CollectorStatistic: &pganalyze_collector.CollectorStatistic{},
CollectorStartedAt: &timestamppb.Timestamp{
Seconds: -62135596800,
Nanos: 0,
},
System: &pganalyze_collector.System{
SystemInformation: &pganalyze_collector.SystemInformation{},
SchedulerStatistic: &pganalyze_collector.SchedulerStatistic{},
MemoryStatistic: &pganalyze_collector.MemoryStatistic{},
CpuInformation: &pganalyze_collector.CPUInformation{},
},
PostgresVersion: &pganalyze_collector.PostgresVersion{},
ServerStatistic: &pganalyze_collector.ServerStatistic{},
Replication: &pganalyze_collector.Replication{},
QueryReferences: []*pganalyze_collector.QueryReference{
&pganalyze_collector.QueryReference{
DatabaseIdx: 0,
RoleIdx: 0,
Fingerprint: fpBuf2,
QueryPlanReferences: []*pganalyze_collector.QueryPlanReference{
&pganalyze_collector.QueryPlanReference{
QueryIdx: 1,
OriginalPlanId: 111,
},
&pganalyze_collector.QueryReference{
DatabaseIdx: 0,
RoleIdx: 0,
Fingerprint: fpBuf1,
&pganalyze_collector.QueryPlanReference{
QueryIdx: 1,
OriginalPlanId: 222,
},
},
QueryInformations: []*pganalyze_collector.QueryInformation{
&pganalyze_collector.QueryInformation{
QueryIdx: 0,
NormalizedQuery: "SELECT * FROM test",
QueryIds: []int64{2},
QueryPlanInformations: []*pganalyze_collector.QueryPlanInformation{
&pganalyze_collector.QueryPlanInformation{
QueryPlanIdx: 0,
ExplainPlan: "Index Scan",
PlanCapturedTime: timestamppb.New(capturedTime),
},
&pganalyze_collector.QueryInformation{
QueryIdx: 1,
NormalizedQuery: "SELECT 1",
QueryIds: []int64{1},
&pganalyze_collector.QueryPlanInformation{
QueryPlanIdx: 1,
ExplainPlan: "Bitmap Heap Scan",
PlanCapturedTime: timestamppb.New(capturedTime),
},
},
QueryStatistics: []*pganalyze_collector.QueryStatistic{
&pganalyze_collector.QueryStatistic{
QueryIdx: 0,
Calls: 13,
QueryPlanStatistics: []*pganalyze_collector.QueryPlanStatistic{
&pganalyze_collector.QueryPlanStatistic{
QueryPlanIdx: 0,
Calls: 2,
},
&pganalyze_collector.QueryStatistic{
QueryIdx: 1,
Calls: 1,
&pganalyze_collector.QueryPlanStatistic{
QueryPlanIdx: 1,
Calls: 24,
},
},
}
expectedJSON, _ := json.Marshal(expected)

// Query: 1, 0, Plan: 0, 1
var expectedAlt pganalyze_collector.FullSnapshot
json.Unmarshal(expectedJSON, &expectedAlt)
expectedAlt.QueryReferences = []*pganalyze_collector.QueryReference{
&pganalyze_collector.QueryReference{
DatabaseIdx: 0,
RoleIdx: 0,
Fingerprint: fpBuf2,
},
&pganalyze_collector.QueryReference{
DatabaseIdx: 0,
RoleIdx: 0,
Fingerprint: fpBuf1,
},
}
expectedAlt.QueryInformations = []*pganalyze_collector.QueryInformation{
&pganalyze_collector.QueryInformation{
QueryIdx: 0,
NormalizedQuery: "SELECT * FROM test",
QueryIds: []int64{2},
},
&pganalyze_collector.QueryInformation{
QueryIdx: 1,
NormalizedQuery: "SELECT 1",
QueryIds: []int64{1},
},
}
expectedAlt.QueryStatistics = []*pganalyze_collector.QueryStatistic{
&pganalyze_collector.QueryStatistic{
QueryIdx: 0,
Calls: 13,
},
&pganalyze_collector.QueryStatistic{
QueryIdx: 1,
Calls: 1,
},
}
expectedJSONAlt, _ := json.Marshal(expectedAlt)

if string(expectedJSON) != string(actualJSON) && string(expectedJSONAlt) != string(actualJSON) {
// Query: 1, 0, Plan: 1, 0
expectedAlt.QueryPlanReferences = []*pganalyze_collector.QueryPlanReference{
&pganalyze_collector.QueryPlanReference{
QueryIdx: 1,
OriginalPlanId: 222,
},
&pganalyze_collector.QueryPlanReference{
QueryIdx: 1,
OriginalPlanId: 111,
},
}
expectedAlt.QueryPlanInformations = []*pganalyze_collector.QueryPlanInformation{
&pganalyze_collector.QueryPlanInformation{
QueryPlanIdx: 0,
ExplainPlan: "Bitmap Heap Scan",
PlanCapturedTime: timestamppb.New(capturedTime),
},
&pganalyze_collector.QueryPlanInformation{
QueryPlanIdx: 1,
ExplainPlan: "Index Scan",
PlanCapturedTime: timestamppb.New(capturedTime),
},
}
expectedAlt.QueryPlanStatistics = []*pganalyze_collector.QueryPlanStatistic{
&pganalyze_collector.QueryPlanStatistic{
QueryPlanIdx: 0,
Calls: 24,
},
&pganalyze_collector.QueryPlanStatistic{
QueryPlanIdx: 1,
Calls: 2,
},
}
expectedJSONAlt2, _ := json.Marshal(expectedAlt)

// Query: 0, 1, Plan: 1, 0
expectedAlt.QueryReferences = []*pganalyze_collector.QueryReference{
&pganalyze_collector.QueryReference{
DatabaseIdx: 0,
RoleIdx: 0,
Fingerprint: fpBuf1,
},
&pganalyze_collector.QueryReference{
DatabaseIdx: 0,
RoleIdx: 0,
Fingerprint: fpBuf2,
},
}
expectedAlt.QueryInformations = []*pganalyze_collector.QueryInformation{
&pganalyze_collector.QueryInformation{
QueryIdx: 0,
NormalizedQuery: "SELECT 1",
QueryIds: []int64{1},
},
&pganalyze_collector.QueryInformation{
QueryIdx: 1,
NormalizedQuery: "SELECT * FROM test",
QueryIds: []int64{2},
},
}
expectedAlt.QueryStatistics = []*pganalyze_collector.QueryStatistic{
&pganalyze_collector.QueryStatistic{
QueryIdx: 0,
Calls: 1,
},
&pganalyze_collector.QueryStatistic{
QueryIdx: 1,
Calls: 13,
},
}
expectedJSONAlt3, _ := json.Marshal(expectedAlt)

if string(expectedJSON) != string(actualJSON) &&
string(expectedJSONAlt) != string(actualJSON) &&
string(expectedJSONAlt2) != string(actualJSON) &&
string(expectedJSONAlt3) != string(actualJSON) {
t.Errorf("\nExpected:%+v\n\tActual: %+v\n\n", string(expectedJSON), string(actualJSON))
}
}

0 comments on commit 903fc2c

Please sign in to comment.