Add files for swift over UDP.
[swifty.git] / src / libswift_udp / tests / transfertest.cpp
1 /*
2  *  transfertest.cpp
3  *  swift
4  *
5  *  Created by Victor Grishchenko on 10/7/09.
6  *  Copyright 2009-2012 TECHNISCHE UNIVERSITEIT DELFT. All rights reserved.
7  *
8  */
9 //#include <gtest/gtest.h>
10 //#include <glog/logging.h>
11 #include "swift.h"
12 #include "compat.h"
13 #include <gtest/gtest.h>
14
15 using namespace swift;
16
17 const char* BTF = "test_file";
18
19 Sha1Hash A,B,C,D,E,AB,CD,ABCD,E0,E000,ABCDE000,ROOT;
20
21
22 TEST(TransferTest,TBHeap) {
23     tbheap tbh;
24     ASSERT_TRUE(tbh.is_empty());
25     tbh.push(tintbin(3,bin_t::NONE));
26     tbh.push(tintbin(1,bin_t::NONE));
27     ASSERT_EQ(2,tbh.size());
28     tbh.push(tintbin(2,bin_t::ALL));
29     ASSERT_EQ(1,tbh.pop().time);
30     ASSERT_EQ(bin_t::ALL,tbh.peek().bin);
31     ASSERT_EQ(2,tbh.pop().time);
32     ASSERT_EQ(3,tbh.pop().time);
33 }
34
35
36 TEST(TransferTest,TransferFile) {
37
38     AB = Sha1Hash(A,B);
39     CD = Sha1Hash(C,D);
40     ABCD = Sha1Hash(AB,CD);
41     E0 = Sha1Hash(E,Sha1Hash::ZERO);
42     E000 = Sha1Hash(E0,Sha1Hash::ZERO);
43     ABCDE000 = Sha1Hash(ABCD,E000);
44     ROOT = ABCDE000;
45     //for (bin_t pos(3,0); !pos.is_all(); pos=pos.parent()) {
46     //    ROOT = Sha1Hash(ROOT,Sha1Hash::ZERO);
47         //printf("m %lli %s\n",(uint64_t)pos.parent(),ROOT.hex().c_str());
48     //}
49     
50     // now, submit a new file
51     
52     FileTransfer* seed_transfer = new FileTransfer(BTF);
53     HashTree* seed = & seed_transfer->file();
54     EXPECT_TRUE(A==seed->hash(bin_t(0,0)));
55     EXPECT_TRUE(E==seed->hash(bin_t(0,4)));
56     EXPECT_TRUE(ABCD==seed->hash(bin_t(2,0)));
57     EXPECT_TRUE(ROOT==seed->root_hash());
58     EXPECT_TRUE(ABCD==seed->peak_hash(0));
59     EXPECT_TRUE(E==seed->peak_hash(1));
60     EXPECT_TRUE(ROOT==seed->root_hash());
61     EXPECT_EQ(4100,seed->size());
62     EXPECT_EQ(5,seed->size_in_chunks());
63     EXPECT_EQ(4100,seed->complete());
64     EXPECT_EQ(4100,seed->seq_complete());
65     EXPECT_EQ(bin_t(2,0),seed->peak(0));
66
67     // retrieve it
68     unlink("copy");
69     FileTransfer* leech_transfer = new FileTransfer("copy",seed->root_hash());
70     HashTree* leech = & leech_transfer->file();
71     leech_transfer->picker().Randomize(0);
72     // transfer peak hashes
73     for(int i=0; i<seed->peak_count(); i++)
74         leech->OfferHash(seed->peak(i),seed->peak_hash(i));
75     ASSERT_EQ(5<<10,leech->size());
76     ASSERT_EQ(5,leech->size_in_chunks());
77     ASSERT_EQ(0,leech->complete());
78     EXPECT_EQ(bin_t(2,0),leech->peak(0));
79     // transfer data and hashes
80     //           ABCD            E000
81     //     AB         CD       E0    0
82     //  AAAA BBBB  CCCC DDDD  E  0  0  0
83     // calculated leech->OfferHash(bin64_t(1,0), seed->hashes[bin64_t(1,0)]);
84     leech->OfferHash(bin_t(1,1), seed->hash(bin_t(1,1)));
85     for (int i=0; i<5; i++) {
86         if (i==2) { // now: stop, save, start
87             delete leech_transfer;
88             leech_transfer = new FileTransfer("copy",seed->root_hash(),false);
89             leech = & leech_transfer->file();
90             leech_transfer->picker().Randomize(0);
91             EXPECT_EQ(2,leech->chunks_complete());
92             EXPECT_EQ(bin_t(2,0),leech->peak(0));
93         }
94         bin_t next = leech_transfer->picker().Pick(seed->ack_out(),1,TINT_NEVER);
95         ASSERT_NE(bin_t::NONE,next);
96         ASSERT_TRUE(next.base_offset()<5);
97         uint8_t buf[1024];         //size_t len = seed->storer->ReadData(next,&buf);
98         size_t len = pread(seed->file_descriptor(),buf,1024,next.base_offset()<<10);
99         bin_t sibling = next.sibling();
100         if (sibling.base_offset()<seed->size_in_chunks())
101             leech->OfferHash(sibling, seed->hash(sibling));
102         uint8_t memo = *buf;
103         *buf = 'z';
104         EXPECT_FALSE(leech->OfferData(next, (char*)buf, len));
105         fprintf(stderr,"offer of bad data was refused, OK\n");
106         *buf = memo;
107         EXPECT_TRUE(leech->OfferData(next, (char*)buf, len));
108     }
109     EXPECT_EQ(4100,leech->size());
110     EXPECT_EQ(5,leech->size_in_chunks());
111     EXPECT_EQ(4100,leech->complete());
112     EXPECT_EQ(4100,leech->seq_complete());
113
114 }
115 /*
116  FIXME
117  - always rehashes (even fresh files)
118  */
119
120 int main (int argc, char** argv) {
121
122     unlink("test_file");
123     unlink("copy");
124     unlink("test_file.mhash");
125     unlink("copy.mhash");
126
127         int f = open(BTF,O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
128         if (f < 0)
129         {
130                 eprintf("Error opening %s\n",BTF);
131                 return -1;
132         }
133     uint8_t buf[1024];
134     memset(buf,'A',1024);
135     A = Sha1Hash(buf,1024);
136     write(f,buf,1024);
137     memset(buf,'B',1024);
138     B = Sha1Hash(buf,1024);
139     write(f,buf,1024);
140     memset(buf,'C',1024);
141     C = Sha1Hash(buf,1024);
142     write(f,buf,1024);
143     memset(buf,'D',1024);
144     D = Sha1Hash(buf,1024);
145     write(f,buf,1024);
146     memset(buf,'E',4);
147     E = Sha1Hash(buf,4);
148     write(f,buf,4);
149         close(f);
150
151         testing::InitGoogleTest(&argc, argv);
152         int ret = RUN_ALL_TESTS();
153
154     return ret;
155 }