This repository has been archived by the owner on Feb 27, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
runner.go
139 lines (114 loc) · 2.95 KB
/
runner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"sort"
"sync"
)
// Privoxy and ss-local working directory.
var workingDir = fmt.Sprintf("%s/Library/Application Support/ShadowsocksX-NG/", HomeDir())
// We need to start multiple process to implement parallel test.
// So we need different port for privoxy and ss-local.
var httpPort = 58321
var socksPort = 56321
// Runner Implement Sort interface.
type Runner struct {
Total float64
Tested float64
Wg *sync.WaitGroup
testers []*Tester
privoxyConfigPath string
configPath string
serverConfigs ServerConfigs
}
// NewRunner Create a new runner.
func NewRunner(configPath string) *Runner {
if !FileExists(configPath) {
panic(fmt.Sprintf("File '%s' not exists.\n", configPath))
}
runner := &Runner{
Wg: &sync.WaitGroup{},
configPath: configPath,
}
runner.parseConfigFile()
runner.createTesters()
runner.Wg.Add(runner.Len())
return runner
}
// Len Tester count
func (r *Runner) Len() int {
return len(r.testers)
}
// Swap tester
func (r *Runner) Swap(i, j int) {
r.testers[i], r.testers[j] = r.testers[j], r.testers[i]
}
// Less Compare tester for ordering.
func (r *Runner) Less(i, j int) bool {
var b2i = map[bool]int8{false: 0, true: 1}
// Sort by Delay, put minimum in the end.
if r.testers[i].IsUsable == r.testers[j].IsUsable {
return r.testers[i].Delay > r.testers[j].Delay
}
// Sort by Usable, put Usable Config in the end.
return b2i[r.testers[i].IsUsable] < b2i[r.testers[j].IsUsable]
}
// See privoxy.config
func (r *Runner) parseConfigFile() {
// Read Config file
content, err := ioutil.ReadFile(r.configPath)
if err != nil {
panic(err)
}
err = json.Unmarshal(content, &r.serverConfigs)
if err != nil {
panic(err)
}
r.Total = float64(len(r.serverConfigs.Configs))
}
// Create testers by shadowsocks configs.
func (r *Runner) createTesters() {
r.testers = make([]*Tester, r.Len())
for _, config := range r.serverConfigs.Configs {
tester := NewTester(httpPort, socksPort)
tester.Config = config
r.testers = append(r.testers, tester)
httpPort = httpPort + 1
socksPort = socksPort + 1
}
}
// Report Generate test report.
func (r *Runner) Report() {
// Sort test results
sort.Sort(r)
for _, tester := range r.testers {
tester.Report()
}
}
// Remove temporary binary files.
func (r *Runner) removeTmpBinaries() {
// Delete temporary ss-local-tmp, privoxy-tmp files/
for _, binary := range []string{"ss-local-tmp", "privoxy-tmp"} {
if FileExists(workingDir + binary) {
err := os.Remove(workingDir + binary)
if err != nil {
fmt.Println(fmt.Sprintf("Remove %s fails: %+v", workingDir+"/"+binary, err))
}
}
}
}
// Clean Remove temporary files. Stop testing processes.
func (r *Runner) Clean() {
r.removeTmpBinaries()
// Delete temporary files.
for _, tester := range r.testers {
tester.Clean()
tester.Exit()
}
}
// Testers Get the underlying testers.
func (r *Runner) Testers() []*Tester {
return r.testers
}