/* example main() function that takes several disk image filenames as * arguments on the command line. * Note that you'll need three images to test recovery after a failure. */ int main(int argc, char **argv) { printf("start\n"); /* create the underlying blkdevs from the images */ struct blkdev *d1 = image_create(argv[1]); struct blkdev *d2 = image_create(argv[2]); /* ... */ printf("created the underlying blkdevs from the images\n"); /* create the mirror */ struct blkdev *disks[] = {d1, d2}; struct blkdev *mirror = mirror_create(disks); printf("created the mirror\n"); /* two asserts - that the mirror create worked, and that the size * is correct. */ assert(mirror != NULL); printf("mirror create worked\n"); assert(mirror->ops->num_blocks(mirror) == d1->ops->num_blocks(d1)); printf("size is correct\n"); /* put your test code here. Errors should exit via either 'assert' * or 'exit(1)' - that way the shell script knows that the test failed. */ /* suggested test codes (from the assignment PDF) You should test that your code: - creates a volume properly - returns the correct length - can handle reads and writes of different sizes, and returns the same data as was written - reads data from the proper location in the images, and doesn't overwrite incorrect locations on write. - continues to read and write correctly after one of the disks fails. (call image_fail() on the image blkdev to force it to fail) - continues to read and write (correctly returning data written before the failure) after the disk is replaced. - reads and writes (returning data written before the first failure) after the other disk fails */ char src[BLOCK_SIZE * 16]; FILE *fp = fopen("/dev/urandom", "r"); assert(fread(src, sizeof(src), 1, fp) == 1); fclose(fp); printf("5\n"); printf("first test\n"); int i, result; for (i = 0; i < 128; i += 16) { result = mirror->ops->write(mirror, i, 16, src); assert(result == SUCCESS); } printf("second test\n"); char dst[BLOCK_SIZE * 16]; for (i = 0; i < 128; i += 16) { result = mirror->ops->read(mirror, i, 16, dst); assert(result == SUCCESS); assert(memcmp(src, dst, 16*BLOCK_SIZE) == 0); } printf("third test\n"); image_fail(d1); for (i = 0; i < 128; i += 16) { result = mirror->ops->read(mirror, i, 16, dst); assert(result == SUCCESS); assert(memcmp(src, dst, 16*BLOCK_SIZE) == 0); } printf("fourth test\n"); struct blkdev *d3 = image_create(argv[3]); assert(mirror_replace(mirror, 0, d3) == SUCCESS); for (i = 0; i < 128; i += 16) { result = mirror->ops->read(mirror, i, 16, dst); assert(result == SUCCESS); assert(memcmp(src, dst, 16*BLOCK_SIZE) == 0); } printf("Mirror Test: SUCCESS\n"); return 0; }
int main(int argc, char **argv) { int part1 = false, part2 = false, part3 = false, part4 = false, part5 = false; while (argv[1][0] == '-') { if (!strcmp(argv[1], "-part1")) part1 = true; if (!strcmp(argv[1], "-part2")) part2 = true; if (!strcmp(argv[1], "-part3")) part3 = true; if (!strcmp(argv[1], "-part4")) part4 = true; if (!strcmp(argv[1], "-part5")) part5 = true; argc--; argv++; } if (!(part1 || part2 || part3 || part4 || part5)) part1 = part2 = part3 = part4 = part5 = true; struct blkdev *disks[10]; int i, ndisks, stripesize = atoi(argv[1]); for (i = 2, ndisks = 0; i < argc; i++) disks[ndisks++] = image_create(argv[i]); disks[ndisks] = NULL; struct blkdev *raid = raid4_create(ndisks, disks, stripesize); assert(raid != NULL); printf("%d \n", ndisks); int nblks = disks[0]->ops->num_blocks(disks[0]); nblks = nblks - (nblks % stripesize); assert(raid->ops->num_blocks(raid) == (ndisks - 1)*nblks); int one_chunk = stripesize * BLOCK_SIZE; int ndata = ndisks - 1; char *buf = calloc(ndata * one_chunk + 100, sizeof(char)); for (i = 0; i < ndata; i++) memset(buf + i * one_chunk, 'A' + i, one_chunk); int result, j; char *buf2 = calloc(ndata * one_chunk + 100, 1); if (part1) { // printf( "Testing part1.\n" ); for (i = 0; i < 16; i++) { result = raid->ops->write(raid, i * ndata * stripesize, ndata * stripesize, buf); assert(result == SUCCESS); } for (i = 0; i < 16; i++) { result = raid->ops->read(raid, i * ndata * stripesize, ndata * stripesize, buf2); assert(result == SUCCESS); assert(memcmp(buf, buf2, ndata * one_chunk) == 0); } /* now we test that the data got onto the disks in the right * places. */ for (i = 0; i < ndata; i++) { for (j = 0; j < 16; j++) { result = disks[i]->ops->read(disks[i], j * stripesize, stripesize, buf2); assert(result == SUCCESS); assert(memcmp(buf + i * one_chunk, buf2, one_chunk) == 0); } } } /* now we test that small writes work */ if (part2) { // printf( "Testing part2.\n" ); for (i = 0; i < ndata; i++) memset(buf + i * one_chunk, 'a' + i, one_chunk); for (i = 0; i < 8; i++) { for (j = 0; j < ndata * stripesize; j ++) { result = raid->ops->write(raid, i * ndata * stripesize + j, 1, buf + j * BLOCK_SIZE); assert(result == SUCCESS); } } for (i = 0; i < 8; i++) { result = raid->ops->read(raid, i * ndata * stripesize, ndata * stripesize, buf2); assert(result == SUCCESS); assert(memcmp(buf, buf2, ndata * one_chunk) == 0); } } /* finally we test that large and overlapping writes work. */ char *big = calloc(5 * ndata * one_chunk + 100, 1); memset(big, 'Q', 5 * ndata * one_chunk); char *big2 = calloc(5 * ndata * one_chunk + 100, 1); int offset = ndata * stripesize / 2; if (part3) { // printf( "Testing part3.\n" ); result = raid->ops->write(raid, offset, 5 * ndata * stripesize, big); assert(result == SUCCESS); result = raid->ops->read(raid, offset, 5 * ndata * stripesize, big2); assert(result == SUCCESS); assert(memcmp(big, big2, 5 * ndata * one_chunk) == 0); /* and check we didn't muck up any previously-written data */ result = raid->ops->read(raid, 0, offset, buf2); assert(result == SUCCESS); assert(memcmp(buf, buf2, offset * BLOCK_SIZE) == 0); result = raid->ops->read(raid, 5 * ndata * stripesize + offset, offset, buf2); assert(result == SUCCESS); assert(memcmp(buf + offset * BLOCK_SIZE, buf2, offset * BLOCK_SIZE) == 0); } /* fail a disk and see that we can read back again */ if (part4) { // printf( "Testing part4.\n" ); char line[2 * ndata * one_chunk]; char line2[2 * ndata * one_chunk]; int i; for (i = 0; i < 2 * ndata * one_chunk; i++) { line[i] = 'a'; line2[i] = 'b'; } assert (raid->ops->write(raid, 0, 2 * ndata * stripesize, line) == SUCCESS) ; image_fail(disks[0]); assert( result = raid->ops->read(raid, 0, 2 * ndata * stripesize, line2) == SUCCESS ); assert(strncmp(line, line2, 2 * ndata * one_chunk) == 0); // printf("OKOKOK\n"); result = raid->ops->write(raid, 8600000, 2 * ndata * stripesize, line); result = raid->ops->read(raid, 8600000, 2 * ndata * stripesize, line2); assert(memcmp(line, line2, 2 * ndata * one_chunk) == 0); } if (part5) { printf( "Testing part5.\n" ); // struct blkdev *xtra = image_create("raid4/disk6.img"); // result = raid4_replace(raid, 0, xtra); // assert(result == SUCCESS); // for (i = 0; i < 16; i++) { // memset(buf2, 0, ndata * stripesize * BLOCK_SIZE); // result = raid->ops->read(raid, i * ndata * stripesize, // ndata * stripesize, buf2); // assert(result == SUCCESS); // assert(strncmp(buf, buf2, ndata * one_chunk) == 0); // } // image_fail(disks[1]); // buf[0] = 'z'; // for (i = 0; i < 16; i++) { // raid->ops->write(raid, i * ndata * stripesize, // ndata * stripesize, buf); // assert(result == SUCCESS); // } // for (i = 0; i < 16; i++) { // result = raid->ops->read(raid, i * ndata * stripesize, // ndata * stripesize, buf2); // assert(result == SUCCESS); // assert(memcmp(buf, buf2, ndata * one_chunk) == 0); // } } printf("RAID4 Test: SUCCESS\n"); return 0; }