Subversion Repositories SvarDOS

Rev

Rev 341 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 341 Rev 616
1
/*
1
/*
2
 * test suite for the unchunk() function.
2
 * test suite for the unchunk() function.
3
 *
3
 *
4
 * Copyright (C) 2021 Mateusz Viste
4
 * Copyright (C) 2021 Mateusz Viste
5
 */
5
 */
6
 
6
 
7
#include <stdio.h>
7
#include <stdio.h>
8
#include <stdlib.h>
8
#include <stdlib.h>
9
#include <string.h>
9
#include <string.h>
10
#include <time.h>
10
#include <time.h>
11
#include <unistd.h>
11
#include <unistd.h>
12
 
12
 
13
#include "unchunk.h"
13
#include "unchunk.h"
14
 
14
 
15
static size_t randchunkdata(void *file_chunked, const void *file_raw, size_t file_raw_len, int maxchunksz) {
15
static size_t randchunkdata(void *file_chunked, const void *file_raw, size_t file_raw_len, int maxchunksz) {
16
  size_t file_raw_read = 0;
16
  size_t file_raw_read = 0;
17
  size_t file_chunked_len = 0;
17
  size_t file_chunked_len = 0;
18
 
18
 
19
  for (;;) {
19
  for (;;) {
20
    int chunklen = (rand() % maxchunksz) + 1;
20
    int chunklen = (rand() % maxchunksz) + 1;
21
    if (file_raw_read + chunklen > file_raw_len) chunklen = file_raw_len - file_raw_read;
21
    if (file_raw_read + chunklen > file_raw_len) chunklen = file_raw_len - file_raw_read;
22
 
22
 
23
    file_chunked_len += sprintf((char *)file_chunked + file_chunked_len, "%x\r\n", chunklen);
23
    file_chunked_len += sprintf((char *)file_chunked + file_chunked_len, "%x\r\n", chunklen);
24
    if (chunklen > 0) memcpy((char *)file_chunked + file_chunked_len, (char *)file_raw + file_raw_read, chunklen);
24
    if (chunklen > 0) memcpy((char *)file_chunked + file_chunked_len, (char *)file_raw + file_raw_read, chunklen);
25
    file_raw_read += chunklen;
25
    file_raw_read += chunklen;
26
    file_chunked_len += chunklen;
26
    file_chunked_len += chunklen;
27
    file_chunked_len += sprintf((char *)file_chunked + file_chunked_len, "\r\n");
27
    file_chunked_len += sprintf((char *)file_chunked + file_chunked_len, "\r\n");
28
    if (chunklen == 0) return(file_chunked_len);
28
    if (chunklen == 0) return(file_chunked_len);
29
  }
29
  }
30
}
30
}
31
 
31
 
32
 
32
 
33
/* writes buffer of fsize bytes to file fname */
33
/* writes buffer of fsize bytes to file fname */
34
static void dumpfile(const char *fname, const void *buff, size_t fsize) {
34
static void dumpfile(const char *fname, const void *buff, size_t fsize) {
35
  FILE *fd;
35
  FILE *fd;
36
  fd = fopen(fname, "wb");
36
  fd = fopen(fname, "wb");
37
  fwrite(buff, 1, fsize, fd);
37
  fwrite(buff, 1, fsize, fd);
38
  fclose(fd);
38
  fclose(fd);
39
}
39
}
40
 
40
 
41
 
41
 
42
int main(int argc, char **argv) {
42
int main(int argc, char **argv) {
43
  unsigned char *file_raw;        /* original file */
43
  unsigned char *file_raw;        /* original file */
44
  unsigned char *file_chunked;    /* chunked version */
44
  unsigned char *file_chunked;    /* chunked version */
45
  unsigned char *file_decoded;    /* after being un-chunked */
45
  unsigned char *file_decoded;    /* after being un-chunked */
46
  size_t file_raw_len;
46
  size_t file_raw_len;
47
  size_t file_chunked_len;
47
  size_t file_chunked_len;
48
  FILE *fd;
48
  FILE *fd;
49
  unsigned int trycount;
49
  unsigned int trycount;
50
 
50
 
51
  if ((argc != 2) || (argv[1][0] == '/')) {
51
  if ((argc != 2) || (argv[1][0] == '/')) {
52
    puts("Usage: unchtest <file>");
52
    puts("Usage: unchtest <file>");
53
    return(1);
53
    return(1);
54
  }
54
  }
55
 
55
 
56
  #define FILESZ_MAX 20000u
56
  #define FILESZ_MAX 20000u
57
 
57
 
58
  file_raw = malloc(FILESZ_MAX);
58
  file_raw = malloc(FILESZ_MAX);
59
  file_chunked = malloc(65000u);
59
  file_chunked = malloc(65000u);
60
  file_decoded = malloc(65000u);
60
  file_decoded = malloc(65000u);
61
  if ((file_raw == NULL) || (file_chunked == NULL) || (file_decoded == NULL)) {
61
  if ((file_raw == NULL) || (file_chunked == NULL) || (file_decoded == NULL)) {
62
    puts("ERROR: out of memory");
62
    puts("ERROR: out of memory");
63
    return(1);
63
    return(1);
64
  }
64
  }
65
 
65
 
66
  fd = fopen(argv[1], "rb");
66
  fd = fopen(argv[1], "rb");
67
  if (fd == NULL) {
67
  if (fd == NULL) {
68
    puts("ERROR: failed to open file");
68
    puts("ERROR: failed to open file");
69
    return(1);
69
    return(1);
70
  }
70
  }
71
  file_raw_len = fread(file_raw, 1, FILESZ_MAX, fd);
71
  file_raw_len = fread(file_raw, 1, FILESZ_MAX, fd);
72
  fclose(fd);
72
  fclose(fd);
73
 
73
 
74
  printf("Loaded '%s' (%zu bytes)\r\n", argv[1], file_raw_len);
74
  printf("Loaded '%s' (%zu bytes)\r\n", argv[1], file_raw_len);
75
  srand(time(NULL));
75
  srand(time(NULL));
76
 
76
 
77
  for (trycount = 0; trycount < 30000; trycount++) {
77
  for (trycount = 0; trycount < 30000; trycount++) {
78
    size_t bytesprocessed = 0;
78
    size_t bytesprocessed = 0;
79
    size_t file_decoded_len = 0;
79
    size_t file_decoded_len = 0;
80
    int maxchunksz;
80
    int maxchunksz;
81
    struct unchunk_state unchstate = {0};
81
    struct unchunk_state unchstate = {0};
82
 
82
 
83
    /* segment file into chunks of random size */
83
    /* segment file into chunks of random size */
84
    maxchunksz = (rand() % 256) + 8;
84
    maxchunksz = (rand() % 256) + 8;
85
    file_chunked_len = randchunkdata(file_chunked, file_raw, file_raw_len, maxchunksz);
85
    file_chunked_len = randchunkdata(file_chunked, file_raw, file_raw_len, maxchunksz);
86
 
86
 
87
    printf("=== TRY %d (CHUNKS: %u BYTES MAX) ======================\r\n", trycount + 1, maxchunksz);
87
    printf("=== TRY %d (CHUNKS: %u BYTES MAX) ======================\r\n", trycount + 1, maxchunksz);
88
 
88
 
89
    for (;;) {
89
    for (;;) {
90
      size_t bytes;
90
      size_t bytes;
91
      int decodedbytes;
91
      int decodedbytes;
92
      static unsigned char buffer[4096];
92
      static unsigned char buffer[4096];
93
 
93
 
94
      bytes = (rand() % 256) + 1;
94
      bytes = (rand() % 256) + 1;
95
      if (bytes > file_chunked_len - bytesprocessed) bytes = file_chunked_len - bytesprocessed;
95
      if (bytes > file_chunked_len - bytesprocessed) bytes = file_chunked_len - bytesprocessed;
96
      printf("processing %4zu bytes of chunked data", bytes);
96
      printf("processing %4zu bytes of chunked data", bytes);
97
      memcpy(buffer, file_chunked + bytesprocessed, bytes);
97
      memcpy(buffer, file_chunked + bytesprocessed, bytes);
98
 
98
 
99
      /* decode the chunked version reading random amounts of data and build a decoded version */
99
      /* decode the chunked version reading random amounts of data and build a decoded version */
100
      decodedbytes = unchunk(buffer, bytes, &unchstate);
100
      decodedbytes = unchunk(buffer, bytes, &unchstate);
101
      printf(" -> decoded into %4d raw bytes\r\n", decodedbytes);
101
      printf(" -> decoded into %4d raw bytes\r\n", decodedbytes);
102
      memcpy(file_decoded + file_decoded_len, buffer, decodedbytes);
102
      memcpy(file_decoded + file_decoded_len, buffer, decodedbytes);
103
      file_decoded_len += decodedbytes;
103
      file_decoded_len += decodedbytes;
104
      bytesprocessed += bytes;
104
      bytesprocessed += bytes;
105
      if (bytesprocessed == file_chunked_len) break;
105
      if (bytesprocessed == file_chunked_len) break;
106
    }
106
    }
107
 
107
 
108
    /* compare decoded and original */
108
    /* compare decoded and original */
109
    if ((file_decoded_len != file_raw_len) || (memcmp(file_decoded, file_raw, file_raw_len) != 0)) {
109
    if ((file_decoded_len != file_raw_len) || (memcmp(file_decoded, file_raw, file_raw_len) != 0)) {
110
      printf("ERROR: decoded file does not match the original. see tst-orig.dat, tst-chnk.txt and tst-unch.dat\r\n");
110
      printf("ERROR: decoded file does not match the original. see tst-orig.dat, tst-chnk.txt and tst-unch.dat\r\n");
111
      dumpfile("tst-orig.dat", file_raw, file_raw_len);
111
      dumpfile("tst-orig.dat", file_raw, file_raw_len);
112
      dumpfile("tst-chnk.dat", file_chunked, file_chunked_len);
112
      dumpfile("tst-chnk.dat", file_chunked, file_chunked_len);
113
      dumpfile("tst-unch.dat", file_decoded, file_decoded_len);
113
      dumpfile("tst-unch.dat", file_decoded, file_decoded_len);
114
      return(1);
114
      return(1);
115
    }
115
    }
116
  }
116
  }
117
 
117
 
118
  printf("OK (%u tests)\r\n", trycount);
118
  printf("OK (%u tests)\r\n", trycount);
119
 
119
 
120
  return(0);
120
  return(0);
121
}
121
}
122
 
122