]> Cypherpunks.ru repositories - nncp.git/blob - src/tx_test.go
4523b6343b8ba6ed17acea1b6f7662a82837af0d
[nncp.git] / src / tx_test.go
1 /*
2 NNCP -- Node to Node copy, utilities for store-and-forward data exchange
3 Copyright (C) 2016-2023 Sergey Matveev <stargrave@stargrave.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 3 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 package nncp
19
20 import (
21         "bytes"
22         "crypto/rand"
23         "io"
24         "os"
25         "path"
26         "testing"
27         "testing/quick"
28
29         xdr "github.com/davecgh/go-xdr/xdr2"
30 )
31
32 func TestTx(t *testing.T) {
33         f := func(
34                 hops uint8,
35                 pathSrc string,
36                 dataSize uint32,
37                 nice, replyNice uint8,
38                 minSize uint32,
39         ) bool {
40                 dataSize %= 1 << 20
41                 data := make([]byte, dataSize)
42                 if _, err := io.ReadFull(rand.Reader, data); err != nil {
43                         panic(err)
44                 }
45                 minSize %= 1 << 20
46                 if len(pathSrc) > int(MaxPathSize) {
47                         pathSrc = pathSrc[:MaxPathSize]
48                 }
49                 hops = hops % 4
50                 spool, err := os.MkdirTemp("", "testtx")
51                 if err != nil {
52                         panic(err)
53                 }
54                 defer os.RemoveAll(spool)
55                 nodeOur, err := NewNodeGenerate()
56                 if err != nil {
57                         panic(err)
58                 }
59                 nodeTgtOur, err := NewNodeGenerate()
60                 if err != nil {
61                         panic(err)
62                 }
63                 nodeTgt := nodeTgtOur.Their()
64                 ctx := Ctx{
65                         Spool:   spool,
66                         LogPath: path.Join(spool, "log.log"),
67                         Debug:   true,
68                         Self:    nodeOur,
69                         SelfId:  nodeOur.Id,
70                         Neigh:   make(map[NodeId]*Node, hops),
71                         Alias:   make(map[string]*NodeId),
72                 }
73                 ctx.Neigh[*nodeOur.Id] = nodeOur.Their()
74                 ctx.Neigh[*nodeTgt.Id] = nodeTgt
75                 privates := make(map[NodeId]*NodeOur, int(hops)+1)
76                 privates[*nodeTgt.Id] = nodeTgtOur
77                 privates[*nodeOur.Id] = nodeOur
78                 for i := uint8(0); i < hops; i++ {
79                         node, err := NewNodeGenerate()
80                         if err != nil {
81                                 panic(err)
82                         }
83                         ctx.Neigh[*node.Id] = node.Their()
84                         privates[*node.Id] = node
85                         nodeTgt.Via = append(nodeTgt.Via, node.Id)
86                 }
87                 pkt, err := NewPkt(PktTypeExec, replyNice, []byte(pathSrc))
88                 if err != nil {
89                         panic(err)
90                 }
91                 src := bytes.NewReader(data)
92                 dstNode, _, _, err := ctx.Tx(
93                         nodeTgt,
94                         pkt,
95                         123,
96                         int64(src.Len()),
97                         int64(minSize),
98                         MaxFileSize,
99                         src,
100                         "pktName",
101                         nil,
102                 )
103                 if err != nil {
104                         return false
105                 }
106
107                 sentJobs := make([]Job, 0, 1)
108                 for txJob := range ctx.Jobs(dstNode.Id, TTx) {
109                         sentJobs = append(sentJobs, txJob)
110                 }
111                 if len(sentJobs) != 1 {
112                         return false
113                 }
114                 txJob := sentJobs[0]
115                 fd, err := os.Open(txJob.Path)
116                 if err != nil {
117                         panic(err)
118                 }
119                 defer fd.Close()
120                 var bufR bytes.Buffer
121                 if _, err = io.Copy(&bufR, fd); err != nil {
122                         panic(err)
123                 }
124                 var bufW bytes.Buffer
125                 vias := append(nodeTgt.Via, nodeTgt.Id)
126                 for i, hopId := range vias {
127                         hopOur := privates[*hopId]
128                         _, foundNode, _, err := PktEncRead(
129                                 hopOur, ctx.Neigh, &bufR, &bufW, true, nil,
130                         )
131                         if err != nil {
132                                 return false
133                         }
134                         if *foundNode.Id != *nodeOur.Id {
135                                 return false
136                         }
137                         bufR, bufW = bufW, bufR
138                         bufW.Reset()
139                         var pkt Pkt
140                         if _, err = xdr.Unmarshal(&bufR, &pkt); err != nil {
141                                 return false
142                         }
143                         if *hopId == *nodeTgt.Id {
144                                 if pkt.Type != PktTypeExec {
145                                         return false
146                                 }
147                                 if pkt.Nice != replyNice {
148                                         return false
149                                 }
150                                 if !bytes.HasPrefix(pkt.Path[:], []byte(pathSrc)) {
151                                         return false
152                                 }
153                                 if !bytes.Equal(bufR.Bytes(), []byte(data)) {
154                                         return false
155                                 }
156                         } else {
157                                 if pkt.Type != PktTypeTrns {
158                                         return false
159                                 }
160                                 if !bytes.Equal(pkt.Path[:MTHSize], vias[i+1][:]) {
161                                         return false
162                                 }
163                         }
164                 }
165                 return true
166         }
167         if err := quick.Check(f, nil); err != nil {
168                 t.Error(err)
169         }
170 }