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