Skip to content
This repository was archived by the owner on Feb 18, 2025. It is now read-only.

Commit db31af5

Browse files
author
Philipp Heckel
committed
Add some unit tests
1 parent 9b07606 commit db31af5

File tree

2 files changed

+113
-2
lines changed

2 files changed

+113
-2
lines changed

go/inst/instance_topology_dao.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -676,10 +676,10 @@ func classifyAndPrioritizeReplicas(replicas []*Instance, includeNonReplicatingIn
676676
}
677677
}
678678

679-
// Sort replicas by priority, promotion rule and name
679+
// Sort replicas by priority (higher number means higher priority), promotion rule and name
680680
sort.Slice(possibleSemiSyncReplicas, func(i, j int) bool {
681681
if possibleSemiSyncReplicas[i].SemiSyncPriority != possibleSemiSyncReplicas[j].SemiSyncPriority {
682-
return possibleSemiSyncReplicas[i].SemiSyncPriority < possibleSemiSyncReplicas[j].SemiSyncPriority
682+
return possibleSemiSyncReplicas[i].SemiSyncPriority > possibleSemiSyncReplicas[j].SemiSyncPriority
683683
}
684684
if possibleSemiSyncReplicas[i].PromotionRule != possibleSemiSyncReplicas[j].PromotionRule {
685685
return possibleSemiSyncReplicas[i].PromotionRule.BetterThan(possibleSemiSyncReplicas[j].PromotionRule)

go/inst/instance_topology_dao_test.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package inst
2+
3+
import (
4+
"github.com/openark/golib/log"
5+
"github.com/openark/orchestrator/go/config"
6+
"testing"
7+
)
8+
9+
func init() {
10+
config.Config.HostnameResolveMethod = "none"
11+
config.MarkConfigurationLoaded()
12+
log.SetLevel(log.ERROR)
13+
}
14+
15+
func newTestReplica(key string, masterKey string, lastCheckValid bool, downtimed bool, semiSyncPriority uint, promotionRule CandidatePromotionRule, replicationState ReplicationThreadState) *Instance {
16+
return &Instance{
17+
Key: InstanceKey{Hostname: key, Port: 3306},
18+
MasterKey: InstanceKey{Hostname: masterKey, Port: 3306},
19+
ReadBinlogCoordinates: BinlogCoordinates{LogFile: "mysql.000001", LogPos: 10},
20+
ReplicationSQLThreadState: replicationState,
21+
ReplicationIOThreadState: replicationState,
22+
IsLastCheckValid: lastCheckValid,
23+
IsDowntimed: downtimed,
24+
SemiSyncPriority: semiSyncPriority,
25+
PromotionRule: promotionRule,
26+
}
27+
}
28+
29+
func expectInstancesMatch(t *testing.T, actual []*Instance, expected []*Instance) {
30+
if len(expected) != len(actual) {
31+
t.Fatalf("Actual instance list %+v does not match expected list %+v", actual, expected)
32+
}
33+
for i := range actual {
34+
if actual[i] != expected[i] {
35+
t.Fatalf("Actual instance %+v does not match expected %+v", actual[i], expected[i])
36+
}
37+
}
38+
}
39+
40+
func TestClassifyAndPrioritizeReplicas_NoPrioritiesSamePromotionRule_NameTiebreaker(t *testing.T) {
41+
replica1 := newTestReplica("replica1", "master1", true, false, 1, NeutralPromoteRule, ReplicationThreadStateRunning)
42+
replica2 := newTestReplica("replica2", "master1", true, false, 1, NeutralPromoteRule, ReplicationThreadStateRunning)
43+
replica3 := newTestReplica("replica3", "master1", true, false, 1, NeutralPromoteRule, ReplicationThreadStateRunning)
44+
replicas := []*Instance{replica3, replica2, replica1} // inverse order!
45+
46+
possibleSemiSyncReplicas, asyncReplicas, excludedReplicas := classifyAndPrioritizeReplicas(replicas, nil)
47+
expectInstancesMatch(t, possibleSemiSyncReplicas, []*Instance{replica1, replica2, replica3})
48+
expectInstancesMatch(t, asyncReplicas, []*Instance{})
49+
expectInstancesMatch(t, excludedReplicas, []*Instance{})
50+
}
51+
52+
func TestClassifyAndPrioritizeReplicas_WithPriorities(t *testing.T) {
53+
replica1 := newTestReplica("replica1", "master1", true, false, 1, NeutralPromoteRule, ReplicationThreadStateRunning)
54+
replica2 := newTestReplica("replica2", "master1", true, false, 3, NeutralPromoteRule, ReplicationThreadStateRunning)
55+
replica3 := newTestReplica("replica3", "master1", true, false, 2, NeutralPromoteRule, ReplicationThreadStateRunning)
56+
replicas := []*Instance{replica1, replica2, replica3}
57+
58+
possibleSemiSyncReplicas, asyncReplicas, excludedReplicas := classifyAndPrioritizeReplicas(replicas, nil)
59+
expectInstancesMatch(t, possibleSemiSyncReplicas, []*Instance{replica2, replica3, replica1})
60+
expectInstancesMatch(t, asyncReplicas, []*Instance{})
61+
expectInstancesMatch(t, excludedReplicas, []*Instance{})
62+
}
63+
64+
func TestClassifyAndPrioritizeReplicas_WithPrioritiesAndPromotionRules_PriorityTakesPrecedence(t *testing.T) {
65+
replica1 := newTestReplica("replica1", "master1", true, false, 1, PreferPromoteRule, ReplicationThreadStateRunning)
66+
replica2 := newTestReplica("replica2", "master1", true, false, 3, MustNotPromoteRule, ReplicationThreadStateRunning)
67+
replica3 := newTestReplica("replica3", "master1", true, false, 2, NeutralPromoteRule, ReplicationThreadStateRunning)
68+
replicas := []*Instance{replica1, replica2, replica3}
69+
70+
possibleSemiSyncReplicas, asyncReplicas, excludedReplicas := classifyAndPrioritizeReplicas(replicas, nil)
71+
expectInstancesMatch(t, possibleSemiSyncReplicas, []*Instance{replica2, replica3, replica1})
72+
expectInstancesMatch(t, asyncReplicas, []*Instance{})
73+
expectInstancesMatch(t, excludedReplicas, []*Instance{})
74+
}
75+
76+
func TestClassifyAndPrioritizeReplicas_LastCheckInvalidAndNotReplication(t *testing.T) {
77+
replica1 := newTestReplica("replica1", "master1", true, false, 1, MustNotPromoteRule, ReplicationThreadStateRunning)
78+
replica2 := newTestReplica("replica2", "master1", true, false, 1, NeutralPromoteRule, ReplicationThreadStateStopped)
79+
replica3 := newTestReplica("replica3", "master1", false, false, 1, PreferPromoteRule, ReplicationThreadStateRunning)
80+
replicas := []*Instance{replica1, replica2, replica3}
81+
82+
possibleSemiSyncReplicas, asyncReplicas, excludedReplicas := classifyAndPrioritizeReplicas(replicas, nil)
83+
expectInstancesMatch(t, possibleSemiSyncReplicas, []*Instance{replica1})
84+
expectInstancesMatch(t, asyncReplicas, []*Instance{})
85+
expectInstancesMatch(t, excludedReplicas, []*Instance{replica2, replica3})
86+
}
87+
88+
func TestClassifyAndPrioritizeReplicas_Downtimed(t *testing.T) {
89+
replica1 := newTestReplica("replica1", "master1", true, false, 1, NeutralPromoteRule, ReplicationThreadStateRunning)
90+
replica2 := newTestReplica("replica2", "master1", true, false, 1, NeutralPromoteRule, ReplicationThreadStateRunning)
91+
replica3 := newTestReplica("replica3", "master1", true, true, 1, MustNotPromoteRule, ReplicationThreadStateRunning)
92+
replica4 := newTestReplica("replica4", "master1", true, false, 0, MustNotPromoteRule, ReplicationThreadStateRunning)
93+
replicas := []*Instance{replica1, replica2, replica3, replica4}
94+
95+
possibleSemiSyncReplicas, asyncReplicas, excludedReplicas := classifyAndPrioritizeReplicas(replicas, nil)
96+
expectInstancesMatch(t, possibleSemiSyncReplicas, []*Instance{replica1, replica2})
97+
expectInstancesMatch(t, asyncReplicas, []*Instance{replica3, replica4})
98+
expectInstancesMatch(t, excludedReplicas, []*Instance{})
99+
}
100+
101+
func TestClassifyAndPrioritizeReplicas_NonReplicatingReplica(t *testing.T) {
102+
replica1 := newTestReplica("replica1", "master1", true, false, 1, NeutralPromoteRule, ReplicationThreadStateRunning)
103+
replica2 := newTestReplica("replica2", "master1", true, false, 1, NeutralPromoteRule, ReplicationThreadStateRunning)
104+
replica3 := newTestReplica("replica3", "master1", true, false, 1, MustNotPromoteRule, ReplicationThreadStateStopped)
105+
replicas := []*Instance{replica1, replica2, replica3}
106+
107+
possibleSemiSyncReplicas, asyncReplicas, excludedReplicas := classifyAndPrioritizeReplicas(replicas, &replica3.Key) // Non-replicating instance
108+
expectInstancesMatch(t, possibleSemiSyncReplicas, []*Instance{replica1, replica2, replica3})
109+
expectInstancesMatch(t, asyncReplicas, []*Instance{})
110+
expectInstancesMatch(t, excludedReplicas, []*Instance{})
111+
}

0 commit comments

Comments
 (0)