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