-
Notifications
You must be signed in to change notification settings - Fork 0
/
main_test.go
149 lines (133 loc) · 4.8 KB
/
main_test.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
140
141
142
143
144
145
146
147
148
149
package main
import (
"crypto/md5"
"fmt"
"hash/crc32"
"strconv"
"sync/atomic"
"testing"
"time"
)
/*
это тест на проверку того что у нас это действительно конвейер
неправильное поведение: накапливать результаты выполнения одной функции, а потом слать их в следующую.
это не похволяет запускать на конвейере бесконечные задачи
правильное поведение: обеспечить беспрепятственный поток
*/
func TestPipeline(t *testing.T) {
var ok = true
var recieved uint32
freeFlowJobs := []job{
job(func(in, out chan interface{}) {
out <- 1
time.Sleep(10 * time.Millisecond)
currRecieved := atomic.LoadUint32(&recieved)
// в чем тут суть
// если вы накапливаете значения, то пока вся функция не отрабоатет - дальше они не пойдут
// тут я проверяю, что счетчик увеличился в следующей функции
// это значит что туда дошло значение прежде чем текущая функция отработала
if currRecieved == 0 {
ok = false
}
}),
job(func(in, out chan interface{}) {
for _ = range in {
atomic.AddUint32(&recieved, 1)
}
}),
}
ExecutePipeline(freeFlowJobs...)
if !ok || recieved == 0 {
t.Errorf("no value free flow - dont collect them")
}
}
func TestSigner(t *testing.T) {
testExpected := "1173136728138862632818075107442090076184424490584241521304_1696913515191343735512658979631549563179965036907783101867_27225454331033649287118297354036464389062965355426795162684_29568666068035183841425683795340791879727309630931025356555_3994492081516972096677631278379039212655368881548151736_4958044192186797981418233587017209679042592862002427381542_4958044192186797981418233587017209679042592862002427381542"
testResult := "NOT_SET"
// это небольшая защита от попыток не вызывать мои функции расчета
// я преопределяю фукции на свои которые инкрементят локальный счетчик
// переопределение возможо потому что я объявил функцию как переменную, в которой лежит функция
var (
DataSignerSalt string = "" // на сервере будет другое значение
OverheatLockCounter uint32
OverheatUnlockCounter uint32
DataSignerMd5Counter uint32
DataSignerCrc32Counter uint32
)
OverheatLock = func() {
atomic.AddUint32(&OverheatLockCounter, 1)
for {
if swapped := atomic.CompareAndSwapUint32(&dataSignerOverheat, 0, 1); !swapped {
fmt.Println("OverheatLock happend")
time.Sleep(time.Second)
} else {
break
}
}
}
OverheatUnlock = func() {
atomic.AddUint32(&OverheatUnlockCounter, 1)
for {
if swapped := atomic.CompareAndSwapUint32(&dataSignerOverheat, 1, 0); !swapped {
fmt.Println("OverheatUnlock happend")
time.Sleep(time.Second)
} else {
break
}
}
}
DataSignerMd5 = func(data string) string {
atomic.AddUint32(&DataSignerMd5Counter, 1)
OverheatLock()
defer OverheatUnlock()
data += DataSignerSalt
dataHash := fmt.Sprintf("%x", md5.Sum([]byte(data)))
time.Sleep(10 * time.Millisecond)
return dataHash
}
DataSignerCrc32 = func(data string) string {
atomic.AddUint32(&DataSignerCrc32Counter, 1)
data += DataSignerSalt
crcH := crc32.ChecksumIEEE([]byte(data))
dataHash := strconv.FormatUint(uint64(crcH), 10)
time.Sleep(time.Second)
return dataHash
}
inputData := []int{0, 1, 1, 2, 3, 5, 8}
// inputData := []int{0,1}
hashSignJobs := []job{
job(func(in, out chan interface{}) {
for _, fibNum := range inputData {
out <- fibNum
}
}),
job(SingleHash),
job(MultiHash),
job(CombineResults),
job(func(in, out chan interface{}) {
dataRaw := <-in
data, ok := dataRaw.(string)
if !ok {
t.Error("cant convert result data to string")
}
testResult = data
}),
}
start := time.Now()
ExecutePipeline(hashSignJobs...)
end := time.Since(start)
expectedTime := 3 * time.Second
if testExpected != testResult {
t.Errorf("results not match\nGot: %v\nExpected: %v", testResult, testExpected)
}
if end > expectedTime {
t.Errorf("execition too long\nGot: %s\nExpected: <%s", end, time.Second*3)
}
// 8 потому что 2 в SingleHash и 6 в MultiHash
if int(OverheatLockCounter) != len(inputData) ||
int(OverheatUnlockCounter) != len(inputData) ||
int(DataSignerMd5Counter) != len(inputData) ||
int(DataSignerCrc32Counter) != len(inputData)*8 {
t.Errorf("not enough hash-func calls")
}
}