1 /*
2 * Copyright (C) by Argonne National Laboratory
3 * See COPYRIGHT in top-level directory
4 */
5
6 #include "mpi.h"
7 #include "mpitestconf.h"
8 #include <stdio.h>
9
10 #ifdef HAVE_STRING_H
11 #include <string.h>
12 #endif
13 #include "mpitest.h"
14
15 /*
16 * openerr - Test that errors on file open are handled correctly and that the
17 * returned error message is accessible
18 */
19 #define BUFLEN 10
20
main(int argc,char * argv[])21 int main(int argc, char *argv[])
22 {
23 MPI_File fh;
24 char emsg[MPI_MAX_ERROR_STRING];
25 int emsglen, err, ec, errs = 0;
26 int amode, rank;
27 const char *name = 0;
28 MPI_Status st;
29 char outbuf[BUFLEN], inbuf[BUFLEN];
30
31 MTest_Init(&argc, &argv);
32
33 name = "not-a-file-to-use";
34 /* Try to open a file that does/should not exist */
35 /* Note that no error message should be printed by MPI_File_open,
36 * even when there is an error */
37 err = MPI_File_open(MPI_COMM_WORLD, name, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh);
38 if (err == MPI_SUCCESS) {
39 errs++;
40 printf("Did not return error when opening a file that does not exist\n");
41 MPI_File_close(&fh);
42 MPI_File_delete(name, MPI_INFO_NULL);
43 } else {
44 MPI_Error_class(err, &ec);
45 MPI_Error_string(err, emsg, &emsglen);
46 MTestPrintfMsg(2, "Error msg from open: %s\n", emsg);
47 if (ec != MPI_ERR_NO_SUCH_FILE && ec != MPI_ERR_IO) {
48 errs++;
49 printf("Did not return class ERR_NO_SUCH_FILE or ERR_IO\n");
50 printf("Returned class %d, message %s\n", ec, emsg);
51 }
52 }
53
54 /* Now, create a file, write data into it; close, then reopen as
55 * read only and try to write to it */
56
57 amode = MPI_MODE_CREATE | MPI_MODE_WRONLY;
58 name = "mpio-test-openerrs";
59
60 err = MPI_File_open(MPI_COMM_WORLD, name, amode, MPI_INFO_NULL, &fh);
61 if (err) {
62 errs++;
63 MTestPrintErrorMsg("Unable to open file for writing", err);
64 } else {
65 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
66 memset(outbuf, 'A' + rank, BUFLEN);
67
68 err = MPI_File_write_at(fh, rank * BUFLEN, outbuf, BUFLEN, MPI_BYTE, &st);
69 if (err) {
70 errs++;
71 MTestPrintErrorMsg("Unable to write file", err);
72 }
73 MPI_File_close(&fh);
74 }
75
76 /* Now, open for read only, and delete on close */
77 amode = MPI_MODE_RDONLY | MPI_MODE_DELETE_ON_CLOSE;
78
79 err = MPI_File_open(MPI_COMM_WORLD, name, amode, MPI_INFO_NULL, &fh);
80 if (err) {
81 errs++;
82 MTestPrintErrorMsg("Unable to reopen file for reading", err);
83 } else {
84 /* Try to read it */
85
86 /* Clear buffer before reading into it */
87
88 memset(inbuf, 0, BUFLEN);
89
90 err = MPI_File_read_at(fh, rank * BUFLEN, inbuf, BUFLEN, MPI_BYTE, &st);
91 if (err) {
92 errs++;
93 MTestPrintErrorMsg("Unable to read file", err);
94 }
95
96 /* Try to write it (should fail) */
97 err = MPI_File_write_at(fh, rank * BUFLEN, outbuf, BUFLEN, MPI_BYTE, &st);
98 if (err == MPI_SUCCESS) {
99 errs++;
100 printf("Write operation succeeded to read-only file\n");
101 } else {
102 /* Look at error class */
103 MPI_Error_class(err, &ec);
104 if (ec != MPI_ERR_READ_ONLY && ec != MPI_ERR_ACCESS) {
105 errs++;
106 printf("Unexpected error class %d when writing to read-only file\n", ec);
107 MTestPrintErrorMsg("Error msg is: ", err);
108 }
109 }
110 err = MPI_File_close(&fh);
111 if (err) {
112 errs++;
113 MTestPrintErrorMsg("Failed to close", err);
114 }
115
116 /* No MPI_Barrier is required here */
117
118 /*
119 * Test open without CREATE to see if DELETE_ON_CLOSE worked.
120 * This should fail if file was deleted correctly.
121 */
122
123 amode = MPI_MODE_RDONLY;
124 err = MPI_File_open(MPI_COMM_WORLD, name, amode, MPI_INFO_NULL, &fh);
125 if (err == MPI_SUCCESS) {
126 errs++;
127 printf("File was not deleted!\n");
128 MPI_File_close(&fh);
129 } else {
130 MPI_Error_class(err, &ec);
131 if (ec != MPI_ERR_NO_SUCH_FILE && ec != MPI_ERR_IO) {
132 errs++;
133 printf("Did not return class ERR_NO_SUCH_FILE or ERR_IO\n");
134 printf("Returned class %d, message %s\n", ec, emsg);
135 }
136 }
137 }
138 /* */
139
140 /* Find out how many errors we saw */
141 MTest_Finalize(errs);
142
143 return MTestReturnValue(errs);
144 }
145