Browse code

Add insertion test as preparation for implementing insertion

Dario Rodriguez authored on 08/03/2019 18:49:22
Showing 3 changed files
... ...
@@ -32,7 +32,7 @@
32 32
 #define UNSAVEDHEADER "REUNSAV\n"
33 33
 #define UNSAVEDVERSION "\n000001\0"
34 34
 
35
-static int redata_hash_gen(redata_t *redata, char *filename, char *resbuf129bytes);
35
+static int redata_hash_gen(redata_t *redata, char *filename, char *buf, int buflen, char *resbuf129bytes);
36 36
 static char *unsaved_genname(char *filename, char *buf, int bufsize);
37 37
 static char *securesave_genname(char *filename, char *buf, int bufsize);
38 38
 static char *genname(char *filename,char *prefix, char *postfix, char *buf, int bufsize);
... ...
@@ -565,7 +565,7 @@ redata_op_redo(redata_t *redata)
565 565
 int
566 566
 redata_hash(redata_t *redata, char *resbuf129bytes)
567 567
 {
568
-        return(redata_hash_gen(redata,NULL,resbuf129bytes));
568
+        return(redata_hash_gen(redata,NULL,NULL,0,resbuf129bytes));
569 569
 }
570 570
 
571 571
 int
... ...
@@ -575,12 +575,21 @@ redata_filehash(redata_t *redata, char *filename, char *resbuf129bytes)
575 575
                 *resbuf129bytes='\0';
576 576
         if(filename==NULL)
577 577
                 return(-1);
578
-        return(redata_hash_gen(redata,filename,resbuf129bytes));
578
+        return(redata_hash_gen(NULL,filename,NULL,0,resbuf129bytes));
579 579
 }
580 580
 
581
+int
582
+redata_memhash(redata_t *redata, char *buf, int buflen, char *resbuf129bytes)
583
+{
584
+        if(resbuf129bytes!=NULL)
585
+                *resbuf129bytes='\0';
586
+        if(buf==NULL || buflen<0)
587
+                return(-1);
588
+        return(redata_hash_gen(NULL,NULL,buf,buflen,resbuf129bytes));
589
+}
581 590
 
582 591
 static int
583
-redata_hash_gen(redata_t *redata, char *filename, char *resbuf129bytes)
592
+redata_hash_gen(redata_t *redata, char *filename, char *buf, int buflen, char *resbuf129bytes)
584 593
 {
585 594
         static char conv[]={"0123456789ABCDEF"};
586 595
         sha3_context sha3;
... ...
@@ -588,9 +597,14 @@ redata_hash_gen(redata_t *redata, char *filename, char *resbuf129bytes)
588 597
         int i,c;
589 598
         int fd=-1;
590 599
         struct stat statbuf;
600
+        if(resbuf129bytes==NULL)
601
+                return(-1);  /* sanity check failed */
591 602
         if(resbuf129bytes!=NULL)
592 603
                 *resbuf129bytes='\0';
593
-        if(redata==NULL || resbuf129bytes==NULL) {
604
+        if((redata==NULL && filename==NULL && buf==NULL)
605
+           || (redata!=NULL && (filename!=NULL || buf!=NULL))
606
+           || (filename!=NULL && (redata!=NULL || buf!=NULL))
607
+           || (buf!=NULL && (redata!=NULL || filename!=NULL))) {
594 608
                 return(-1); /* sanity check failed */
595 609
         }
596 610
         if(filename!=NULL) {
... ...
@@ -601,10 +615,10 @@ redata_hash_gen(redata_t *redata, char *filename, char *resbuf129bytes)
601 615
                 }
602 616
         }
603 617
         sha3_Init512(&sha3);
604
-        if(filename==NULL) {
618
+        if(redata!=NULL) {
605 619
                 for(i=0;i<redata->sizechunks;i++)
606 620
                         sha3_Update(&sha3,(void *) redata->chunks[i]->data,redata->chunks[i]->useddata);
607
-        } else {
621
+        } else if(filename!=NULL) {
608 622
                 char buf[16384];
609 623
                 int totalread,nread;
610 624
                 for(totalread=0,nread=0;totalread<statbuf.st_size;totalread+=nread,nread=0) {
... ...
@@ -615,6 +629,8 @@ redata_hash_gen(redata_t *redata, char *filename, char *resbuf129bytes)
615 629
                         sha3_Update(&sha3,(void *) buf,nread);
616 630
                 }
617 631
                 close(fd),fd=-1;
632
+        } else if(buf!=NULL) {
633
+                sha3_Update(&sha3,(void *) buf,buflen);
618 634
         }
619 635
         hash=(unsigned char *)sha3_Finalize(&sha3);
620 636
         for(i=0;i<64;i++) {
... ...
@@ -86,4 +86,5 @@ int redata_op_redo(redata_t *redata);
86 86
 
87 87
 int redata_hash(redata_t *redata, char *resbuf129bytes);
88 88
 int redata_filehash(redata_t *redata, char *filename, char *resbuf129bytes);
89
+int redata_memhash(redata_t *redata, char *buf, int buflen, char *resbuf129bytes);
89 90
 
... ...
@@ -15,6 +15,7 @@
15 15
 #include <string.h>
16 16
 #include <limits.h>
17 17
 #include <fcntl.h>
18
+#include <errno.h>
18 19
 
19 20
 #include "recenteditor_data.h"
20 21
 
... ...
@@ -30,7 +31,11 @@ typedef struct test_t  {
30 31
         int int2;
31 32
 } test_t;
32 33
 
34
+static char *malloc_data(int size, int seed);
35
+static int write_file(char *filename, char *buf, int buflen);
36
+
33 37
 char *test_newfile(redata_t *redata, char *filename, char *dummy, int filesize, int dummy2);
38
+char *test_edit(redata_t *redata, char *filename, char *edits, int filesize, int seed);
34 39
 
35 40
 int
36 41
 main(int argc, char *argv[])
... ...
@@ -42,7 +47,7 @@ main(int argc, char *argv[])
42 47
                 {"newfile_32768",test_newfile,PREFIX "FILE", NULL, 32768, 0},
43 48
                 {"newfile_32769",test_newfile,PREFIX "FILE", NULL, 32769, 0},
44 49
                 {"newfile_131072",test_newfile,PREFIX "FILE", NULL, 131072, 0},
45
-
50
+                {"testedit_add",test_edit,PREFIX "EDIT", "A,0,$,Testing add$",0,0},
46 51
         };
47 52
         redata_t *redata;
48 53
         int i;
... ...
@@ -67,31 +72,56 @@ main(int argc, char *argv[])
67 72
         if(nerrors==0)
68 73
                 fprintf(stderr,"All tests passed OK\n");
69 74
         else
70
-                fprintf(stderr,"%i tests failed of %i total tests.\n",nerrors,i);
75
+                fprintf(stderr,"%i test(s) failed of %i tests run.\n",nerrors,i);
71 76
         redata_free(redata),redata=NULL;
72 77
         return((nerrors==0)?0:1);
73 78
 }
74 79
 
80
+static char *
81
+malloc_data(int size, int seed)
82
+{
83
+        char *mem;
84
+        int i;
85
+        if(size<=0 || (mem=malloc(size))==NULL)
86
+                return(NULL);
87
+        memset(mem,0,size);
88
+        if(seed==0) {
89
+                for(i=0;i<size;i++)
90
+                        ((unsigned char *)mem)[i]=(i%256);
91
+        } else {
92
+                srandom(*((unsigned int *)(&seed)));
93
+                for(i=0;i<size;i++)
94
+                        ((unsigned char *)mem)[i]=(random()&0xff);
95
+        }
96
+        return(mem);
97
+
98
+}
99
+
100
+static int
101
+write_file(char *filename, char *buf, int buflen)
102
+{
103
+        int fd;
104
+        if((fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0644))==-1) {
105
+                free(buf),buf=NULL;
106
+                return(-1);
107
+        }
108
+        write(fd,buf,buflen);
109
+        close(fd),fd=-1;
110
+        return(0);
111
+}
112
+
75 113
 char *
76 114
 test_newfile(redata_t *redata, char *filename, char *dummy, int filesize, int dummy2)
77 115
 {
78 116
         char *mem;
79 117
         char hash129_pre[129];
80 118
         char hash129_post[129];
81
-        int fd,i;
82
-fprintf(stderr,"\ntest_newfile(%s%s%s,%s,%i,%i);\nResult: ",(filename!=NULL)?"\"":"",(filename!=NULL)?filename:"NULL",(filename!=NULL)?"\"":"",(dummy!=NULL)?dummy:"NULL",filesize,dummy2);
119
+fprintf(stderr,"\ntest_newfile(%s%s%s,%s%s%s,%i,%i);\nResult: ",(filename!=NULL)?"\"":"",(filename!=NULL)?filename:"NULL",(filename!=NULL)?"\"":"",(dummy!=NULL)?"\"":"",(dummy!=NULL)?dummy:"NULL",(dummy!=NULL)?"\"":"",filesize,dummy2);
83 120
         /* prepare file for loading */
84
-        if((mem=malloc(filesize))==NULL)
121
+        if((mem=malloc_data(filesize,0))==NULL)
85 122
                 return("insuf. mem. for temp. buffer");
86
-        memset(mem,0,filesize);
87
-        for(i=0;i<filesize;i++)
88
-                ((unsigned char *)mem)[i]=(filesize%256);
89
-        if((fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0644))==-1) {
90
-                free(mem),mem=NULL;
123
+        if(write_file(filename,mem,filesize)==-1)
91 124
                 return("couldn't create temporary file");
92
-        }
93
-        write(fd,mem,filesize);
94
-        close(fd),fd=-1;
95 125
         redata_filehash(redata,filename,hash129_pre);
96 126
         free(mem),mem=NULL;
97 127
         /* load file */
... ...
@@ -113,3 +143,116 @@ fprintf(stderr,"\ntest_newfile(%s%s%s,%s,%i,%i);\nResult: ",(filename!=NULL)?"\"
113 143
         return(TEST_OK);
114 144
 }
115 145
 
146
+char *
147
+test_edit(redata_t *redata, char *filename, char *edits, int filesize, int seed)
148
+{
149
+        static char errorbuf[256];
150
+        char progress[256];
151
+        int k;
152
+        int cursize;
153
+        char *ptr;
154
+        int l;
155
+        char *mem;
156
+        char endcode;
157
+        char *ptrend;
158
+        int size;
159
+        char hash129_memold[129];
160
+        char hash129_mem[129];
161
+        char hash129_redata[129];
162
+        mem=NULL;
163
+fprintf(stderr,"\ntest_edit(%s%s%s,%s%s%s,%i,%i);\nResult: ",(filename!=NULL)?"\"":"",(filename!=NULL)?filename:"NULL",(filename!=NULL)?"\"":"",(edits!=NULL)?"\"":"",(edits!=NULL)?edits:"NULL",(edits!=NULL)?"\"":"",filesize,seed);
164
+        /* two passes: k==0 count needed memory, k==1 do edits */
165
+        for(k=0,cursize=filesize,progress[0]='\0';k<2;k++,cursize=0,progress[0]='\0') {
166
+                for(ptr=edits;*ptr!='\0';) {
167
+                        if(k!=0) {
168
+                                redata_memhash(redata,mem,cursize,hash129_memold);
169
+                        }
170
+                        if((l=strlen(progress))<(sizeof(progress)-1)) {
171
+                                progress[l]=(l<(sizeof(progress)-2))?*ptr:'+';
172
+                                progress[l+1]='\0';
173
+                        }
174
+                        if(*ptr=='A') {
175
+                                /* A,<insertpos>,<endchar>,<text><endchar> */
176
+                                ptr++;
177
+                                ptr+=(*ptr==',')?1:0;
178
+                                errno=0;
179
+                                l=(int)strtol(ptr,&ptr,10);
180
+                                if(errno!=0 || l<0 || l>cursize) {
181
+                                        if(mem!=NULL)
182
+                                                free(mem),mem=NULL;
183
+                                        return("test_edit(): error parsing position");
184
+                                }
185
+                                ptr+=(*ptr==',')?1:0;
186
+                                endcode=*ptr;
187
+                                ptr+=(*ptr!='\0')?1:0;
188
+                                ptrend=strchr(ptr,endcode);
189
+                                ptrend=(ptrend==NULL)?ptr+strlen(ptr):ptrend;
190
+                                size=ptrend-ptr;
191
+                                if(k!=0) {
192
+                                        /* editing */
193
+                                        memmove(mem+l+size,mem+l,size);
194
+                                        memcpy(mem+l,ptr,size);
195
+                                        redata_op_add(redata,ptr,size,l);
196
+                                }
197
+                                cursize+=size;
198
+                                ptr+=size;
199
+                                ptr+=(*ptr!='\0')?1:0;
200
+                        } else {
201
+                                if(mem!=NULL)
202
+                                        free(mem),mem=NULL;
203
+                                snprintf(errorbuf,sizeof(errorbuf),
204
+                                  "test_edit(): unknown edit action at pos %i: '%c' (progress: %s)",(int) (ptr-edits),*ptr,progress);
205
+                                errorbuf[sizeof(errorbuf)-1]='\0';
206
+                                return(errorbuf);
207
+                        }
208
+                        if(k!=0) {
209
+                                redata_hash(redata,hash129_redata);
210
+                                redata_memhash(redata,mem,cursize,hash129_mem);
211
+                                if(strcmp(hash129_redata,hash129_mem)!=0) {
212
+                                        if(mem!=NULL)
213
+                                                free(mem),mem=NULL;
214
+                                        snprintf(errorbuf,sizeof(errorbuf),
215
+                                          "corrupted edit before pos %i (progress: %s)",(int) (ptr-edits),progress);
216
+                                        errorbuf[sizeof(errorbuf)-1]='\0';
217
+                                        return(errorbuf);
218
+                                }
219
+                                redata_op_undo(redata);
220
+                                redata_hash(redata,hash129_redata);
221
+                                if(strcmp(hash129_redata,hash129_memold)!=0) {
222
+                                        if(mem!=NULL)
223
+                                                free(mem),mem=NULL;
224
+                                        snprintf(errorbuf,sizeof(errorbuf),
225
+                                          "corrupted undo before pos %i (progress: %s)",(int) (ptr-edits),progress);
226
+                                        errorbuf[sizeof(errorbuf)-1]='\0';
227
+                                        return(errorbuf);
228
+                                }
229
+                                redata_op_redo(redata);
230
+                                redata_hash(redata,hash129_redata);
231
+                                if(strcmp(hash129_redata,hash129_mem)!=0) {
232
+                                        if(mem!=NULL)
233
+                                                free(mem),mem=NULL;
234
+                                        snprintf(errorbuf,sizeof(errorbuf),
235
+                                          "corrupted redo before pos %i (progress: %s)",(int) (ptr-edits),progress);
236
+                                        errorbuf[sizeof(errorbuf)-1]='\0';
237
+                                        return(errorbuf);
238
+                                }
239
+                        }
240
+                }
241
+                if(k==0) {
242
+                        /* reserve memory, do init */
243
+                        if((mem=malloc_data(cursize,seed))==NULL)
244
+                                return("insuf. mem. for temp. buffer");
245
+                        if(write_file(filename,mem,filesize)==-1)
246
+                                return("couldn't create temporary file");
247
+                        if(redata_load(redata,filename,0)!=0) {
248
+                                unlink(filename);
249
+                                return("couldn't load file");
250
+                        }
251
+                        unlink(filename);
252
+                }
253
+        }
254
+        if(mem!=NULL)
255
+                free(mem),mem=NULL;
256
+        return(TEST_OK);
257
+}
258
+