~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to ivle/testfilespace.py

  • Committer: mattgiuca
  • Date: 2008-07-15 07:19:34 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:875
Added "migrations" directory, which contains incremental database update
    scripts.
Updated users.sql, uniqueness key on offering table.
Added migration matching this update to the migrations directory. Mm handy!

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# IVLE - Informatics Virtual Learning Environment
2
 
# Copyright (C) 2007-2008 The University of Melbourne
3
 
#
4
 
# This program is free software; you can redistribute it and/or modify
5
 
# it under the terms of the GNU General Public License as published by
6
 
# the Free Software Foundation; either version 2 of the License, or
7
 
# (at your option) any later version.
8
 
#
9
 
# This program is distributed in the hope that it will be useful,
10
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
# GNU General Public License for more details.
13
 
#
14
 
# You should have received a copy of the GNU General Public License
15
 
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
 
 
18
 
# Module: TestFilespace
19
 
# Author: Dilshan Angampitiya
20
 
#         Steven Bird (revisions)
21
 
#         David Coles (revisions and moved to module)
22
 
# Date:   24/1/2008
23
 
 
24
 
import StringIO
25
 
 
26
 
class TestFilespace:
27
 
    """
28
 
    Our dummy file system which is accessed by code being tested.
29
 
    Implemented as a dictionary which maps filenames to strings
30
 
    """
31
 
    def __init__(self, files=None):
32
 
        "Initialise, optionally with filename-filedata pairs"
33
 
 
34
 
        if files == None:
35
 
            files = {}
36
 
 
37
 
        # dict mapping files to strings
38
 
        self._files = {}
39
 
        self._files.update(files)
40
 
        # set of file names
41
 
        self._modified_files = set([])
42
 
        # dict mapping files to stringIO objects
43
 
        self._open_files = {}
44
 
 
45
 
    def add_file(self, filename, data):
46
 
        " Add a file to the filespace "
47
 
        self._files[filename] = data
48
 
 
49
 
    def openfile(self, filename, mode='r'):
50
 
        """ Open a file from the filespace with the given mode.
51
 
        Return a StringIO subclass object with the file contents.
52
 
        """
53
 
        # currently very messy, needs to be cleaned up
54
 
        # Probably most of this should be in the initialiser to the TestStringIO
55
 
        
56
 
        import re
57
 
 
58
 
        if filename in self._open_files:
59
 
            raise IOError("File already open: %s" %filename)
60
 
 
61
 
        if not re.compile("[rwa][+b]{0,2}").match(mode):
62
 
            raise IOError("invalid mode %s" %mode)
63
 
        
64
 
        ## TODO: validate filename?
65
 
        
66
 
        mode.replace("b",'')
67
 
        
68
 
        # initialise the file properly (truncate/create if required)
69
 
        if mode[0] == 'w':
70
 
            self._files[filename] = ''
71
 
            self._modified_files.add(filename)
72
 
        elif filename not in self._files:
73
 
            if mode[0] == 'a':
74
 
                self._files[filename] = ''
75
 
                self._modified_files.add(filename)
76
 
            else:
77
 
                raise IOError(2, "Access to file denied: %s" %filename)
78
 
 
79
 
        # for append mode, remember the existing data
80
 
        if mode[0] == 'a':
81
 
            existing_data = self._files[filename]
82
 
        else:
83
 
            existing_data = ""
84
 
 
85
 
        # determine what operations are allowed
86
 
        reading_ok = (len(mode) == 2 or mode[0] == 'r')
87
 
        writing_ok = (len(mode) == 2 or mode[0] in 'wa')
88
 
 
89
 
        # for all writing modes, start off with blank file
90
 
        if mode[0] == 'w':
91
 
            initial_data = ''
92
 
        else:
93
 
            initial_data = self._files[filename]
94
 
 
95
 
        file_object = TestStringIO(initial_data, filename, self, reading_ok, writing_ok, existing_data)
96
 
        self._open_files[filename] = file_object
97
 
        
98
 
        return file_object
99
 
 
100
 
    def flush_all(self):
101
 
        """ Flush all open files
102
 
        """
103
 
        for file_object in self._open_files.values():
104
 
            file_object.flush()
105
 
 
106
 
    def updatefile(self,filename, data):
107
 
        """ Callback function used by an open file to inform when it has been updated.
108
 
        """
109
 
        if filename in self._open_files:
110
 
            self._files[filename] = data
111
 
            if self._open_files[filename].is_modified():
112
 
                self._modified_files.add(filename)
113
 
        else:
114
 
            raise IOError(2, "Access to file denied: %s" %filename)
115
 
 
116
 
    def closefile(self, filename):
117
 
        """ Callback function used by an open file to inform when it has been closed.
118
 
        """
119
 
        if filename in self._open_files:
120
 
            del self._open_files[filename]
121
 
 
122
 
    def get_modified_files(self):
123
 
        """" A subset of the filespace containing only those files which have been
124
 
        modified
125
 
        """
126
 
        modified_files = {}
127
 
        for filename in self._modified_files:
128
 
            modified_files[filename] = self._files[filename]
129
 
 
130
 
        return modified_files
131
 
 
132
 
    def get_open_files(self):
133
 
        " Return the names of all open files "
134
 
        return self._open_files.keys()
135
 
            
136
 
    def copy(self):
137
 
        """ Return a copy of the current filespace.
138
 
        Only the files are copied, not the modified or open file lists.
139
 
        """
140
 
        self.flush_all()
141
 
        return TestFilespace(self._files)
142
 
 
143
 
class TestStringIO(StringIO.StringIO):
144
 
    """
145
 
    A subclass of StringIO which acts as a file in our dummy file system
146
 
    """
147
 
    def __init__(self, string, filename, filespace, reading_ok, writing_ok, existing_data):
148
 
        """ Initialise with the filedata, file name and infomation on what ops are
149
 
        acceptable """
150
 
        StringIO.StringIO.__init__(self, string)
151
 
        self._filename = filename
152
 
        self._filespace = filespace
153
 
        self._reading_ok = reading_ok
154
 
        self._writing_ok = writing_ok
155
 
        self._existing_data = existing_data
156
 
        self._modified = False
157
 
        self._open = True
158
 
 
159
 
    # Override all standard file ops. Make sure that they are valid with the given
160
 
    # permissions and if so then call the corresponding method in StringIO
161
 
    
162
 
    def read(self, *args):
163
 
        if not self._reading_ok:
164
 
            raise IOError(9, "Bad file descriptor")
165
 
        else:
166
 
            return StringIO.StringIO.read(self, *args)
167
 
 
168
 
    def readline(self, *args):
169
 
        if not self._reading_ok:
170
 
            raise IOError(9, "Bad file descriptor")
171
 
        else:
172
 
            return StringIO.StringIO.readline(self, *args)
173
 
 
174
 
    def readlines(self, *args):
175
 
        if not self._reading_ok:
176
 
            raise IOError(9, "Bad file descriptor")
177
 
        else:
178
 
            return StringIO.StringIO.readlines(self, *args)
179
 
 
180
 
    def seek(self, *args):
181
 
        if not self._reading_ok:
182
 
            raise IOError(9, "Bad file descriptor")
183
 
        else:
184
 
            return StringIO.StringIO.seek(self, *args)
185
 
 
186
 
    def truncate(self, *args):
187
 
        self._modified = True
188
 
        if not self._writing_ok:
189
 
            raise IOError(9, "Bad file descriptor")
190
 
        else:
191
 
            return StringIO.StringIO.truncate(self, *args)
192
 
        
193
 
    def write(self, *args):
194
 
        self._modified = True
195
 
        if not self._writing_ok:
196
 
            raise IOError(9, "Bad file descriptor")
197
 
        else:
198
 
            return StringIO.StringIO.write(self, *args)
199
 
 
200
 
    def writelines(self, *args):
201
 
        self._modified = True
202
 
        if not self._writing_ok:
203
 
            raise IOError(9, "Bad file descriptor")
204
 
        else:
205
 
            return StringIO.StringIO.writelines(self, *args)
206
 
 
207
 
    def is_modified(self):
208
 
        " Return true if the file has been written to, or truncated"
209
 
        return self._modified
210
 
        
211
 
    def flush(self):
212
 
        " Update the contents of the filespace with the new data "
213
 
        self._filespace.updatefile(self._filename, self._existing_data+self.getvalue())
214
 
        return StringIO.StringIO.flush(self)
215
 
 
216
 
    def close(self):
217
 
        " Flush the file and close it "
218
 
        self.flush()
219
 
        self._filespace.closefile(self._filename)
220
 
        return StringIO.StringIO.close(self)
221