2
# Copyright (c) 2005-2010 Apple Inc. All rights reserved.
4
# Licensed under the Apache License, Version 2.0 (the "License");
5
# you may not use this file except in compliance with the License.
6
# You may obtain a copy of the License at
8
# http://www.apache.org/licenses/LICENSE-2.0
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
19
from twext.python.plistlib import readPlistFromString
22
from twext.python.filepath import CachingFilePath as FilePath
23
from twisted.internet import reactor
24
from twisted.internet.defer import inlineCallbacks, Deferred, returnValue
26
from twistedcaldav.config import config
27
from twistedcaldav.test.util import TestCase, CapturingProcessProtocol
28
from calendarserver.tools.util import getDirectory
31
class GatewayTestCase(TestCase):
34
super(GatewayTestCase, self).setUp()
36
testRoot = os.path.join(os.path.dirname(__file__), "gateway")
37
templateName = os.path.join(testRoot, "caldavd.plist")
38
templateFile = open(templateName)
39
template = templateFile.read()
42
newConfig = template % {
43
"ServerRoot" : os.path.abspath(config.ServerRoot),
45
configFilePath = FilePath(os.path.join(config.ConfigRoot, "caldavd.plist"))
46
configFilePath.setContent(newConfig)
48
self.configFileName = configFilePath.path
49
config.load(self.configFileName)
51
origUsersFile = FilePath(os.path.join(os.path.dirname(__file__),
52
"gateway", "users-groups.xml"))
53
copyUsersFile = FilePath(os.path.join(config.DataRoot, "accounts.xml"))
54
origUsersFile.copyTo(copyUsersFile)
56
origResourcesFile = FilePath(os.path.join(os.path.dirname(__file__),
57
"gateway", "resources-locations.xml"))
58
copyResourcesFile = FilePath(os.path.join(config.DataRoot, "resources.xml"))
59
origResourcesFile.copyTo(copyResourcesFile)
61
origAugmentFile = FilePath(os.path.join(os.path.dirname(__file__),
62
"gateway", "augments.xml"))
63
copyAugmentFile = FilePath(os.path.join(config.DataRoot, "augments.xml"))
64
origAugmentFile.copyTo(copyAugmentFile)
66
# Make sure trial puts the reactor in the right state, by letting it
67
# run one reactor iteration. (Ignore me, please.)
69
reactor.callLater(0, d.callback, True)
73
def runCommand(self, command, error=False):
75
Run the given command by feeding it as standard input to
76
calendarserver_command_gateway in a subprocess.
79
if isinstance(command, unicode):
80
command = command.encode("utf-8")
82
sourceRoot = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
83
python = sys.executable
84
gateway = os.path.join(sourceRoot, "bin", "calendarserver_command_gateway")
86
args = [python, gateway, "-f", self.configFileName]
88
args.append("--error")
93
reactor.spawnProcess(CapturingProcessProtocol(deferred, command), python, args, env=os.environ, path=cwd)
94
output = yield deferred
96
plist = readPlistFromString(output)
97
except xml.parsers.expat.ExpatError, e:
98
print "Error (%s) parsing (%s)" % (e, output)
104
def test_getLocationList(self):
105
results = yield self.runCommand(command_getLocationList)
106
self.assertEquals(len(results["result"]), 10)
109
def test_getLocationAttributes(self):
110
results = yield self.runCommand(command_createLocation)
111
results = yield self.runCommand(command_getLocationAttributes)
112
self.assertEquals(results["result"]["Building"], "Test Building")
113
self.assertEquals(results["result"]["City"], "Cupertino")
114
self.assertEquals(results["result"]["Capacity"], "40")
115
self.assertEquals(results["result"]["Description"], "Test Description")
116
self.assertEquals(results["result"]["ZIP"], "95014")
117
self.assertEquals(results["result"]["Floor"], "First")
118
self.assertEquals(results["result"]["RecordName"], ["createdlocation01"])
119
self.assertEquals(results["result"]["State"], "CA")
120
self.assertEquals(results["result"]["Street"], "1 Infinite Loop")
121
self.assertEquals(results["result"]["RealName"], "Created Location 01 %s" % unichr(208))
122
self.assertEquals(results["result"]["Comment"], "Test Comment")
123
self.assertEquals(results["result"]["AutoSchedule"], True)
124
self.assertEquals(set(results["result"]["ReadProxies"]), set(['user03', 'user04']))
125
self.assertEquals(set(results["result"]["WriteProxies"]), set(['user05', 'user06']))
128
def test_getResourceList(self):
129
results = yield self.runCommand(command_getResourceList)
130
self.assertEquals(len(results["result"]), 10)
133
def test_getResourceAttributes(self):
134
results = yield self.runCommand(command_createResource)
135
results = yield self.runCommand(command_getResourceAttributes)
136
self.assertEquals(results["result"]["Comment"], "Test Comment")
137
self.assertEquals(results["result"]["Type"], "Computer")
138
self.assertEquals(set(results["result"]["ReadProxies"]), set(['user03', 'user04']))
139
self.assertEquals(set(results["result"]["WriteProxies"]), set(['user05', 'user06']))
142
def test_createLocation(self):
143
directory = getDirectory()
145
record = directory.recordWithUID("836B1B66-2E9A-4F46-8B1C-3DD6772C20B2")
146
self.assertEquals(record, None)
148
yield self.runCommand(command_createLocation)
150
directory.flushCaches()
152
# This appears to be necessary in order for record.autoSchedule to
153
# reflect the change prior to the directory record expiration
154
augmentService = directory.serviceForRecordType(directory.recordType_locations).augmentService
155
augmentService.refresh()
157
record = directory.recordWithUID("836B1B66-2E9A-4F46-8B1C-3DD6772C20B2")
158
self.assertEquals(record.fullName.decode("utf-8"), "Created Location 01 %s" % unichr(208))
160
self.assertNotEquals(record, None)
161
self.assertEquals(record.autoSchedule, True)
163
self.assertEquals(record.extras["comment"], "Test Comment")
164
self.assertEquals(record.extras["building"], "Test Building")
165
self.assertEquals(record.extras["floor"], "First")
166
self.assertEquals(record.extras["capacity"], "40")
167
self.assertEquals(record.extras["street"], "1 Infinite Loop")
168
self.assertEquals(record.extras["city"], "Cupertino")
169
self.assertEquals(record.extras["state"], "CA")
170
self.assertEquals(record.extras["zip"], "95014")
171
self.assertEquals(record.extras["country"], "USA")
172
self.assertEquals(record.extras["phone"], "(408) 555-1212")
174
results = yield self.runCommand(command_getLocationAttributes)
175
self.assertEquals(set(results["result"]["ReadProxies"]), set(['user03', 'user04']))
176
self.assertEquals(set(results["result"]["WriteProxies"]), set(['user05', 'user06']))
179
def test_setLocationAttributes(self):
180
directory = getDirectory()
182
yield self.runCommand(command_createLocation)
183
record = directory.recordWithUID("836B1B66-2E9A-4F46-8B1C-3DD6772C20B2")
184
yield self.runCommand(command_setLocationAttributes)
185
directory.flushCaches()
187
# This appears to be necessary in order for record.autoSchedule to
189
augmentService = directory.serviceForRecordType(directory.recordType_locations).augmentService
190
augmentService.refresh()
192
record = directory.recordWithUID("836B1B66-2E9A-4F46-8B1C-3DD6772C20B2")
194
self.assertEquals(record.extras["comment"], "Updated Test Comment")
195
self.assertEquals(record.extras["building"], "Updated Test Building")
196
self.assertEquals(record.extras["floor"], "Second")
197
self.assertEquals(record.extras["capacity"], "41")
198
self.assertEquals(record.extras["street"], "2 Infinite Loop")
199
self.assertEquals(record.extras["city"], "Updated Cupertino")
200
self.assertEquals(record.extras["state"], "Updated CA")
201
self.assertEquals(record.extras["zip"], "95015")
202
self.assertEquals(record.extras["country"], "Updated USA")
203
self.assertEquals(record.extras["phone"], "(408) 555-1213")
204
self.assertEquals(record.autoSchedule, True)
206
results = yield self.runCommand(command_getLocationAttributes)
207
self.assertEquals(results["result"]["AutoSchedule"], True)
208
self.assertEquals(set(results["result"]["ReadProxies"]), set(['user03']))
209
self.assertEquals(set(results["result"]["WriteProxies"]), set(['user05', 'user06', 'user07']))
213
def test_destroyLocation(self):
214
directory = getDirectory()
216
record = directory.recordWithUID("location01")
217
self.assertNotEquals(record, None)
219
yield self.runCommand(command_deleteLocation)
221
directory.flushCaches()
222
record = directory.recordWithUID("location01")
223
self.assertEquals(record, None)
226
def test_createResource(self):
227
directory = getDirectory()
229
record = directory.recordWithUID("AF575A61-CFA6-49E1-A0F6-B5662C9D9801")
230
self.assertEquals(record, None)
232
yield self.runCommand(command_createResource)
234
directory.flushCaches()
235
record = directory.recordWithUID("AF575A61-CFA6-49E1-A0F6-B5662C9D9801")
236
self.assertNotEquals(record, None)
239
def test_setResourceAttributes(self):
240
directory = getDirectory()
242
yield self.runCommand(command_createResource)
243
directory.flushCaches()
244
record = directory.recordWithUID("AF575A61-CFA6-49E1-A0F6-B5662C9D9801")
245
self.assertEquals(record.fullName, "Laptop 1")
247
yield self.runCommand(command_setResourceAttributes)
249
directory.flushCaches()
250
record = directory.recordWithUID("AF575A61-CFA6-49E1-A0F6-B5662C9D9801")
251
self.assertEquals(record.fullName, "Updated Laptop 1")
254
def test_destroyResource(self):
255
directory = getDirectory()
257
record = directory.recordWithUID("resource01")
258
self.assertNotEquals(record, None)
260
yield self.runCommand(command_deleteResource)
262
directory.flushCaches()
263
record = directory.recordWithUID("resource01")
264
self.assertEquals(record, None)
267
def test_addWriteProxy(self):
268
results = yield self.runCommand(command_addWriteProxy)
269
self.assertEquals(len(results["result"]["Proxies"]), 1)
272
def test_removeWriteProxy(self):
273
results = yield self.runCommand(command_addWriteProxy)
274
results = yield self.runCommand(command_removeWriteProxy)
275
self.assertEquals(len(results["result"]["Proxies"]), 0)
279
command_addReadProxy = """<?xml version="1.0" encoding="UTF-8"?>
280
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
281
<plist version="1.0">
284
<string>addReadProxy</string>
286
<string>locations:location01</string>
288
<string>users:user03</string>
293
command_addWriteProxy = """<?xml version="1.0" encoding="UTF-8"?>
294
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
295
<plist version="1.0">
298
<string>addWriteProxy</string>
300
<string>locations:location01</string>
302
<string>users:user01</string>
307
command_createLocation = """<?xml version="1.0" encoding="UTF-8"?>
308
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
309
<plist version="1.0">
312
<string>createLocation</string>
313
<key>AutoSchedule</key>
315
<key>GeneratedUID</key>
316
<string>836B1B66-2E9A-4F46-8B1C-3DD6772C20B2</string>
318
<string>Created Location 01 %s</string>
319
<key>RecordName</key>
321
<string>createdlocation01</string>
324
<string>Test Comment</string>
325
<key>Description</key>
326
<string>Test Description</string>
328
<string>Test Building</string>
330
<string>First</string>
334
<string>1 Infinite Loop</string>
336
<string>Cupertino</string>
340
<string>95014</string>
344
<string>(408) 555-1212</string>
345
<key>ReadProxies</key>
347
<string>users:user03</string>
348
<string>users:user04</string>
350
<key>WriteProxies</key>
352
<string>users:user05</string>
353
<string>users:user06</string>
360
command_createResource = """<?xml version="1.0" encoding="UTF-8"?>
361
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
362
<plist version="1.0">
365
<string>createResource</string>
366
<key>AutoSchedule</key>
368
<key>GeneratedUID</key>
369
<string>AF575A61-CFA6-49E1-A0F6-B5662C9D9801</string>
371
<string>Laptop 1</string>
373
<string>Computer</string>
374
<key>RecordName</key>
376
<string>laptop1</string>
379
<string>Test Comment</string>
380
<key>ReadProxies</key>
382
<string>users:user03</string>
383
<string>users:user04</string>
385
<key>WriteProxies</key>
387
<string>users:user05</string>
388
<string>users:user06</string>
394
command_deleteLocation = """<?xml version="1.0" encoding="UTF-8"?>
395
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
396
<plist version="1.0">
399
<string>deleteLocation</string>
400
<key>GeneratedUID</key>
401
<string>location01</string>
406
command_deleteResource = """<?xml version="1.0" encoding="UTF-8"?>
407
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
408
<plist version="1.0">
411
<string>deleteResource</string>
412
<key>GeneratedUID</key>
413
<string>resource01</string>
418
command_getLocationList = """<?xml version="1.0" encoding="UTF-8"?>
419
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
420
<plist version="1.0">
423
<string>getLocationList</string>
428
command_getResourceList = """<?xml version="1.0" encoding="UTF-8"?>
429
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
430
<plist version="1.0">
433
<string>getResourceList</string>
438
command_listReadProxies = """<?xml version="1.0" encoding="UTF-8"?>
439
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
440
<plist version="1.0">
443
<string>listReadProxies</string>
445
<string>836B1B66-2E9A-4F46-8B1C-3DD6772C20B2</string>
450
command_listWriteProxies = """<?xml version="1.0" encoding="UTF-8"?>
451
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
452
<plist version="1.0">
455
<string>listWriteProxies</string>
457
<string>836B1B66-2E9A-4F46-8B1C-3DD6772C20B2</string>
462
command_removeReadProxy = """<?xml version="1.0" encoding="UTF-8"?>
463
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
464
<plist version="1.0">
467
<string>removeReadProxy</string>
469
<string>locations:location01</string>
471
<string>users:user03</string>
476
command_removeWriteProxy = """<?xml version="1.0" encoding="UTF-8"?>
477
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
478
<plist version="1.0">
481
<string>removeWriteProxy</string>
483
<string>locations:location01</string>
485
<string>users:user01</string>
490
command_setLocationAttributes = """<?xml version="1.0" encoding="UTF-8"?>
491
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
492
<plist version="1.0">
495
<string>setLocationAttributes</string>
496
<key>AutoSchedule</key>
498
<key>GeneratedUID</key>
499
<string>836B1B66-2E9A-4F46-8B1C-3DD6772C20B2</string>
501
<string>Updated Location 01</string>
502
<key>RecordName</key>
504
<string>createdlocation01</string>
507
<string>Updated Test Comment</string>
508
<key>Description</key>
509
<string>Updated Test Description</string>
511
<string>Updated Test Building</string>
513
<string>Second</string>
517
<string>2 Infinite Loop</string>
519
<string>Updated Cupertino</string>
521
<string>Updated CA</string>
523
<string>95015</string>
525
<string>Updated USA</string>
527
<string>(408) 555-1213</string>
528
<key>ReadProxies</key>
530
<string>users:user03</string>
532
<key>WriteProxies</key>
534
<string>users:user05</string>
535
<string>users:user06</string>
536
<string>users:user07</string>
542
command_getLocationAttributes = """<?xml version="1.0" encoding="UTF-8"?>
543
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
544
<plist version="1.0">
547
<string>getLocationAttributes</string>
548
<key>GeneratedUID</key>
549
<string>836B1B66-2E9A-4F46-8B1C-3DD6772C20B2</string>
554
command_setResourceAttributes = """<?xml version="1.0" encoding="UTF-8"?>
555
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
556
<plist version="1.0">
559
<string>setResourceAttributes</string>
560
<key>AutoSchedule</key>
562
<key>GeneratedUID</key>
563
<string>AF575A61-CFA6-49E1-A0F6-B5662C9D9801</string>
565
<string>Updated Laptop 1</string>
566
<key>RecordName</key>
568
<string>laptop1</string>
574
command_getResourceAttributes = """<?xml version="1.0" encoding="UTF-8"?>
575
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
576
<plist version="1.0">
579
<string>getResourceAttributes</string>
580
<key>GeneratedUID</key>
581
<string>AF575A61-CFA6-49E1-A0F6-B5662C9D9801</string>