• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# Copyright (c) 2012 Amazon.com, Inc. or its affiliates.  All Rights Reserved
3#
4# Permission is hereby granted, free of charge, to any person obtaining a
5# copy of this software and associated documentation files (the
6# "Software"), to deal in the Software without restriction, including
7# without limitation the rights to use, copy, modify, merge, publish, dis-
8# tribute, sublicense, and/or sell copies of the Software, and to permit
9# persons to whom the Software is furnished to do so, subject to the fol-
10# lowing conditions:
11#
12# The above copyright notice and this permission notice shall be included
13# in all copies or substantial portions of the Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
17# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
18# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21# IN THE SOFTWARE.
22#
23
24from tests.unit import unittest
25from tests.unit import AWSMockServiceTestCase
26
27from boto.ec2.securitygroup import SecurityGroup
28from boto.rds import RDSConnection
29from boto.rds.vpcsecuritygroupmembership import VPCSecurityGroupMembership
30from boto.rds.parametergroup import ParameterGroup
31from boto.rds.logfile import LogFile, LogFileObject
32
33import xml.sax.saxutils as saxutils
34
35class TestRDSConnection(AWSMockServiceTestCase):
36    connection_class = RDSConnection
37
38    def setUp(self):
39        super(TestRDSConnection, self).setUp()
40
41    def default_body(self):
42        return """
43        <DescribeDBInstancesResponse>
44          <DescribeDBInstancesResult>
45            <DBInstances>
46                <DBInstance>
47                  <Iops>2000</Iops>
48                  <BackupRetentionPeriod>1</BackupRetentionPeriod>
49                  <MultiAZ>false</MultiAZ>
50                  <DBInstanceStatus>backing-up</DBInstanceStatus>
51                  <DBInstanceIdentifier>mydbinstance2</DBInstanceIdentifier>
52                  <PreferredBackupWindow>10:30-11:00</PreferredBackupWindow>
53                  <PreferredMaintenanceWindow>wed:06:30-wed:07:00</PreferredMaintenanceWindow>
54                  <OptionGroupMembership>
55                    <OptionGroupName>default:mysql-5-5</OptionGroupName>
56                    <Status>in-sync</Status>
57                  </OptionGroupMembership>
58                  <AvailabilityZone>us-west-2b</AvailabilityZone>
59                  <ReadReplicaDBInstanceIdentifiers/>
60                  <Engine>mysql</Engine>
61                  <PendingModifiedValues/>
62                  <LicenseModel>general-public-license</LicenseModel>
63                  <DBParameterGroups>
64                    <DBParameterGroup>
65                      <ParameterApplyStatus>in-sync</ParameterApplyStatus>
66                      <DBParameterGroupName>default.mysql5.5</DBParameterGroupName>
67                    </DBParameterGroup>
68                  </DBParameterGroups>
69                  <Endpoint>
70                    <Port>3306</Port>
71                    <Address>mydbinstance2.c0hjqouvn9mf.us-west-2.rds.amazonaws.com</Address>
72                  </Endpoint>
73                  <EngineVersion>5.5.27</EngineVersion>
74                  <DBSecurityGroups>
75                    <DBSecurityGroup>
76                      <Status>active</Status>
77                      <DBSecurityGroupName>default</DBSecurityGroupName>
78                    </DBSecurityGroup>
79                  </DBSecurityGroups>
80                  <VpcSecurityGroups>
81                    <VpcSecurityGroupMembership>
82                      <VpcSecurityGroupId>sg-1</VpcSecurityGroupId>
83                      <Status>active</Status>
84                    </VpcSecurityGroupMembership>
85                  </VpcSecurityGroups>
86                  <DBName>mydb2</DBName>
87                  <AutoMinorVersionUpgrade>true</AutoMinorVersionUpgrade>
88                  <InstanceCreateTime>2012-10-03T22:01:51.047Z</InstanceCreateTime>
89                  <AllocatedStorage>200</AllocatedStorage>
90                  <DBInstanceClass>db.m1.large</DBInstanceClass>
91                  <MasterUsername>awsuser</MasterUsername>
92                  <StatusInfos>
93                    <DBInstanceStatusInfo>
94                      <Message></Message>
95                      <Normal>true</Normal>
96                      <Status>replicating</Status>
97                      <StatusType>read replication</StatusType>
98                    </DBInstanceStatusInfo>
99                  </StatusInfos>
100                  <DBSubnetGroup>
101                    <VpcId>990524496922</VpcId>
102                    <SubnetGroupStatus>Complete</SubnetGroupStatus>
103                    <DBSubnetGroupDescription>My modified DBSubnetGroup</DBSubnetGroupDescription>
104                    <DBSubnetGroupName>mydbsubnetgroup</DBSubnetGroupName>
105                    <Subnets>
106                      <Subnet>
107                        <SubnetStatus>Active</SubnetStatus>
108                        <SubnetIdentifier>subnet-7c5b4115</SubnetIdentifier>
109                        <SubnetAvailabilityZone>
110                        <Name>us-east-1c</Name>
111                      </SubnetAvailabilityZone>
112                      </Subnet>
113                      <Subnet>
114                        <SubnetStatus>Active</SubnetStatus>
115                        <SubnetIdentifier>subnet-7b5b4112</SubnetIdentifier>
116                        <SubnetAvailabilityZone>
117                          <Name>us-east-1b</Name>
118                        </SubnetAvailabilityZone>
119                      </Subnet>
120                      <Subnet>
121                        <SubnetStatus>Active</SubnetStatus>
122                        <SubnetIdentifier>subnet-3ea6bd57</SubnetIdentifier>
123                        <SubnetAvailabilityZone>
124                          <Name>us-east-1d</Name>
125                        </SubnetAvailabilityZone>
126                      </Subnet>
127                    </Subnets>
128                  </DBSubnetGroup>
129              </DBInstance>
130            </DBInstances>
131          </DescribeDBInstancesResult>
132        </DescribeDBInstancesResponse>
133        """
134
135    def test_get_all_db_instances(self):
136        self.set_http_response(status_code=200)
137        response = self.service_connection.get_all_dbinstances('instance_id')
138        self.assertEqual(len(response), 1)
139        self.assert_request_parameters({
140            'Action': 'DescribeDBInstances',
141            'DBInstanceIdentifier': 'instance_id',
142        }, ignore_params_values=['Version'])
143        db = response[0]
144        self.assertEqual(db.id, 'mydbinstance2')
145        self.assertEqual(db.create_time, '2012-10-03T22:01:51.047Z')
146        self.assertEqual(db.engine, 'mysql')
147        self.assertEqual(db.status, 'backing-up')
148        self.assertEqual(db.allocated_storage, 200)
149        self.assertEqual(
150            db.endpoint,
151            (u'mydbinstance2.c0hjqouvn9mf.us-west-2.rds.amazonaws.com', 3306))
152        self.assertEqual(db.instance_class, 'db.m1.large')
153        self.assertEqual(db.master_username, 'awsuser')
154        self.assertEqual(db.availability_zone, 'us-west-2b')
155        self.assertEqual(db.backup_retention_period, 1)
156        self.assertEqual(db.preferred_backup_window, '10:30-11:00')
157        self.assertEqual(db.preferred_maintenance_window,
158                         'wed:06:30-wed:07:00')
159        self.assertEqual(db.latest_restorable_time, None)
160        self.assertEqual(db.multi_az, False)
161        self.assertEqual(db.iops, 2000)
162        self.assertEqual(db.pending_modified_values, {})
163
164        self.assertEqual(db.parameter_group.name,
165                         'default.mysql5.5')
166        self.assertEqual(db.parameter_group.description, None)
167        self.assertEqual(db.parameter_group.engine, None)
168
169        self.assertEqual(db.security_group.owner_id, None)
170        self.assertEqual(db.security_group.name, 'default')
171        self.assertEqual(db.security_group.description, None)
172        self.assertEqual(db.security_group.ec2_groups, [])
173        self.assertEqual(db.security_group.ip_ranges, [])
174        self.assertEqual(len(db.status_infos), 1)
175        self.assertEqual(db.status_infos[0].message, '')
176        self.assertEqual(db.status_infos[0].normal, True)
177        self.assertEqual(db.status_infos[0].status, 'replicating')
178        self.assertEqual(db.status_infos[0].status_type, 'read replication')
179        self.assertEqual(db.vpc_security_groups[0].status, 'active')
180        self.assertEqual(db.vpc_security_groups[0].vpc_group, 'sg-1')
181        self.assertEqual(db.license_model, 'general-public-license')
182        self.assertEqual(db.engine_version, '5.5.27')
183        self.assertEqual(db.auto_minor_version_upgrade, True)
184        self.assertEqual(db.subnet_group.name, 'mydbsubnetgroup')
185
186
187class TestRDSCCreateDBInstance(AWSMockServiceTestCase):
188    connection_class = RDSConnection
189
190    def setUp(self):
191        super(TestRDSCCreateDBInstance, self).setUp()
192
193    def default_body(self):
194        return """
195        <CreateDBInstanceResponse xmlns="http://rds.amazonaws.com/doc/2013-05-15/">
196            <CreateDBInstanceResult>
197                <DBInstance>
198                    <ReadReplicaDBInstanceIdentifiers/>
199                    <Engine>mysql</Engine>
200                    <PendingModifiedValues>
201                        <MasterUserPassword>****</MasterUserPassword>
202                    </PendingModifiedValues>
203                    <BackupRetentionPeriod>0</BackupRetentionPeriod>
204                    <MultiAZ>false</MultiAZ>
205                    <LicenseModel>general-public-license</LicenseModel>
206                    <DBSubnetGroup>
207                        <VpcId>990524496922</VpcId>
208                        <SubnetGroupStatus>Complete</SubnetGroupStatus>
209                        <DBSubnetGroupDescription>description</DBSubnetGroupDescription>
210                        <DBSubnetGroupName>subnet_grp1</DBSubnetGroupName>
211                        <Subnets>
212                            <Subnet>
213                                <SubnetStatus>Active</SubnetStatus>
214                                <SubnetIdentifier>subnet-7c5b4115</SubnetIdentifier>
215                                <SubnetAvailabilityZone>
216                                    <Name>us-east-1c</Name>
217                                </SubnetAvailabilityZone>
218                            </Subnet>
219                            <Subnet>
220                                <SubnetStatus>Active</SubnetStatus>
221                                <SubnetIdentifier>subnet-7b5b4112</SubnetIdentifier>
222                                <SubnetAvailabilityZone>
223                                    <Name>us-east-1b</Name>
224                                </SubnetAvailabilityZone>
225                            </Subnet>
226                            <Subnet>
227                                <SubnetStatus>Active</SubnetStatus>
228                                <SubnetIdentifier>subnet-3ea6bd57</SubnetIdentifier>
229                                <SubnetAvailabilityZone>
230                                    <Name>us-east-1d</Name>
231                                </SubnetAvailabilityZone>
232                            </Subnet>
233                        </Subnets>
234                    </DBSubnetGroup>
235                    <DBInstanceStatus>creating</DBInstanceStatus>
236                    <EngineVersion>5.1.50</EngineVersion>
237                    <DBInstanceIdentifier>simcoprod01</DBInstanceIdentifier>
238                    <DBParameterGroups>
239                        <DBParameterGroup>
240                            <ParameterApplyStatus>in-sync</ParameterApplyStatus>
241                            <DBParameterGroupName>default.mysql5.1</DBParameterGroupName>
242                        </DBParameterGroup>
243                    </DBParameterGroups>
244                    <DBSecurityGroups>
245                        <DBSecurityGroup>
246                            <Status>active</Status>
247                            <DBSecurityGroupName>default</DBSecurityGroupName>
248                        </DBSecurityGroup>
249                    </DBSecurityGroups>
250                    <PreferredBackupWindow>00:00-00:30</PreferredBackupWindow>
251                    <AutoMinorVersionUpgrade>true</AutoMinorVersionUpgrade>
252                    <PreferredMaintenanceWindow>sat:07:30-sat:08:00</PreferredMaintenanceWindow>
253                        <AllocatedStorage>10</AllocatedStorage>
254                        <DBInstanceClass>db.m1.large</DBInstanceClass>
255                        <MasterUsername>master</MasterUsername>
256                </DBInstance>
257            </CreateDBInstanceResult>
258            <ResponseMetadata>
259                <RequestId>2e5d4270-8501-11e0-bd9b-a7b1ece36d51</RequestId>
260            </ResponseMetadata>
261        </CreateDBInstanceResponse>
262        """
263
264    def test_create_db_instance_param_group_name(self):
265        self.set_http_response(status_code=200)
266        db = self.service_connection.create_dbinstance(
267            'SimCoProd01',
268            10,
269            'db.m1.large',
270            'master',
271            'Password01',
272            param_group='default.mysql5.1',
273            db_subnet_group_name='dbSubnetgroup01',
274            backup_retention_period=0)
275
276        self.assert_request_parameters({
277            'Action': 'CreateDBInstance',
278            'AllocatedStorage': 10,
279            'AutoMinorVersionUpgrade': 'true',
280            'BackupRetentionPeriod': 0,
281            'DBInstanceClass': 'db.m1.large',
282            'DBInstanceIdentifier': 'SimCoProd01',
283            'DBParameterGroupName': 'default.mysql5.1',
284            'DBSubnetGroupName': 'dbSubnetgroup01',
285            'Engine': 'MySQL5.1',
286            'MasterUsername': 'master',
287            'MasterUserPassword': 'Password01',
288            'Port': 3306
289        }, ignore_params_values=['Version'])
290
291        self.assertEqual(db.id, 'simcoprod01')
292        self.assertEqual(db.engine, 'mysql')
293        self.assertEqual(db.status, 'creating')
294        self.assertEqual(db.allocated_storage, 10)
295        self.assertEqual(db.instance_class, 'db.m1.large')
296        self.assertEqual(db.master_username, 'master')
297        self.assertEqual(db.multi_az, False)
298        self.assertEqual(db.pending_modified_values,
299            {'MasterUserPassword': '****'})
300
301        self.assertEqual(db.parameter_group.name,
302                         'default.mysql5.1')
303        self.assertEqual(db.parameter_group.description, None)
304        self.assertEqual(db.parameter_group.engine, None)
305        self.assertEqual(db.backup_retention_period, 0)
306
307    def test_create_db_instance_param_group_instance(self):
308        self.set_http_response(status_code=200)
309        param_group = ParameterGroup()
310        param_group.name = 'default.mysql5.1'
311        db = self.service_connection.create_dbinstance(
312            'SimCoProd01',
313            10,
314            'db.m1.large',
315            'master',
316            'Password01',
317            param_group=param_group,
318            db_subnet_group_name='dbSubnetgroup01')
319
320        self.assert_request_parameters({
321            'Action': 'CreateDBInstance',
322            'AllocatedStorage': 10,
323            'AutoMinorVersionUpgrade': 'true',
324            'DBInstanceClass': 'db.m1.large',
325            'DBInstanceIdentifier': 'SimCoProd01',
326            'DBParameterGroupName': 'default.mysql5.1',
327            'DBSubnetGroupName': 'dbSubnetgroup01',
328            'Engine': 'MySQL5.1',
329            'MasterUsername': 'master',
330            'MasterUserPassword': 'Password01',
331            'Port': 3306,
332        }, ignore_params_values=['Version'])
333
334        self.assertEqual(db.id, 'simcoprod01')
335        self.assertEqual(db.engine, 'mysql')
336        self.assertEqual(db.status, 'creating')
337        self.assertEqual(db.allocated_storage, 10)
338        self.assertEqual(db.instance_class, 'db.m1.large')
339        self.assertEqual(db.master_username, 'master')
340        self.assertEqual(db.multi_az, False)
341        self.assertEqual(db.pending_modified_values,
342            {'MasterUserPassword': '****'})
343        self.assertEqual(db.parameter_group.name,
344                         'default.mysql5.1')
345        self.assertEqual(db.parameter_group.description, None)
346        self.assertEqual(db.parameter_group.engine, None)
347
348
349class TestRDSConnectionRestoreDBInstanceFromPointInTime(AWSMockServiceTestCase):
350    connection_class = RDSConnection
351
352    def setUp(self):
353        super(TestRDSConnectionRestoreDBInstanceFromPointInTime, self).setUp()
354
355    def default_body(self):
356        return """
357        <RestoreDBInstanceToPointInTimeResponse xmlns="http://rds.amazonaws.com/doc/2013-05-15/">
358          <RestoreDBInstanceToPointInTimeResult>
359            <DBInstance>
360              <ReadReplicaDBInstanceIdentifiers/>
361              <Engine>mysql</Engine>
362              <PendingModifiedValues/>
363              <BackupRetentionPeriod>1</BackupRetentionPeriod>
364              <MultiAZ>false</MultiAZ>
365              <LicenseModel>general-public-license</LicenseModel>
366              <DBInstanceStatus>creating</DBInstanceStatus>
367              <EngineVersion>5.1.50</EngineVersion>
368              <DBInstanceIdentifier>restored-db</DBInstanceIdentifier>
369              <DBParameterGroups>
370                <DBParameterGroup>
371                  <ParameterApplyStatus>in-sync</ParameterApplyStatus>
372                  <DBParameterGroupName>default.mysql5.1</DBParameterGroupName>
373                </DBParameterGroup>
374              </DBParameterGroups>
375              <DBSecurityGroups>
376                <DBSecurityGroup>
377                  <Status>active</Status>
378                  <DBSecurityGroupName>default</DBSecurityGroupName>
379                </DBSecurityGroup>
380              </DBSecurityGroups>
381              <PreferredBackupWindow>00:00-00:30</PreferredBackupWindow>
382              <AutoMinorVersionUpgrade>true</AutoMinorVersionUpgrade>
383              <PreferredMaintenanceWindow>sat:07:30-sat:08:00</PreferredMaintenanceWindow>
384              <AllocatedStorage>10</AllocatedStorage>
385              <DBInstanceClass>db.m1.large</DBInstanceClass>
386              <MasterUsername>master</MasterUsername>
387            </DBInstance>
388          </RestoreDBInstanceToPointInTimeResult>
389          <ResponseMetadata>
390            <RequestId>1ef546bc-850b-11e0-90aa-eb648410240d</RequestId>
391          </ResponseMetadata>
392        </RestoreDBInstanceToPointInTimeResponse>
393        """
394
395    def test_restore_dbinstance_from_point_in_time(self):
396        self.set_http_response(status_code=200)
397        db = self.service_connection.restore_dbinstance_from_point_in_time(
398            'simcoprod01',
399            'restored-db',
400            True)
401
402        self.assert_request_parameters({
403            'Action': 'RestoreDBInstanceToPointInTime',
404            'SourceDBInstanceIdentifier': 'simcoprod01',
405            'TargetDBInstanceIdentifier': 'restored-db',
406            'UseLatestRestorableTime': 'true',
407        }, ignore_params_values=['Version'])
408
409        self.assertEqual(db.id, 'restored-db')
410        self.assertEqual(db.engine, 'mysql')
411        self.assertEqual(db.status, 'creating')
412        self.assertEqual(db.allocated_storage, 10)
413        self.assertEqual(db.instance_class, 'db.m1.large')
414        self.assertEqual(db.master_username, 'master')
415        self.assertEqual(db.multi_az, False)
416
417        self.assertEqual(db.parameter_group.name,
418                         'default.mysql5.1')
419        self.assertEqual(db.parameter_group.description, None)
420        self.assertEqual(db.parameter_group.engine, None)
421
422    def test_restore_dbinstance_from_point_in_time__db_subnet_group_name(self):
423        self.set_http_response(status_code=200)
424        db = self.service_connection.restore_dbinstance_from_point_in_time(
425            'simcoprod01',
426            'restored-db',
427            True,
428            db_subnet_group_name='dbsubnetgroup')
429
430        self.assert_request_parameters({
431            'Action': 'RestoreDBInstanceToPointInTime',
432            'SourceDBInstanceIdentifier': 'simcoprod01',
433            'TargetDBInstanceIdentifier': 'restored-db',
434            'UseLatestRestorableTime': 'true',
435            'DBSubnetGroupName': 'dbsubnetgroup',
436        }, ignore_params_values=['Version'])
437
438    def test_create_db_instance_vpc_sg_str(self):
439        self.set_http_response(status_code=200)
440        vpc_security_groups = [
441            VPCSecurityGroupMembership(self.service_connection, 'active', 'sg-1'),
442            VPCSecurityGroupMembership(self.service_connection, None, 'sg-2')]
443
444        db = self.service_connection.create_dbinstance(
445            'SimCoProd01',
446            10,
447            'db.m1.large',
448            'master',
449            'Password01',
450            param_group='default.mysql5.1',
451            db_subnet_group_name='dbSubnetgroup01',
452            vpc_security_groups=vpc_security_groups)
453
454        self.assert_request_parameters({
455            'Action': 'CreateDBInstance',
456            'AllocatedStorage': 10,
457            'AutoMinorVersionUpgrade': 'true',
458            'DBInstanceClass': 'db.m1.large',
459            'DBInstanceIdentifier': 'SimCoProd01',
460            'DBParameterGroupName': 'default.mysql5.1',
461            'DBSubnetGroupName': 'dbSubnetgroup01',
462            'Engine': 'MySQL5.1',
463            'MasterUsername': 'master',
464            'MasterUserPassword': 'Password01',
465            'Port': 3306,
466            'VpcSecurityGroupIds.member.1': 'sg-1',
467            'VpcSecurityGroupIds.member.2': 'sg-2'
468        }, ignore_params_values=['Version'])
469
470    def test_create_db_instance_vpc_sg_obj(self):
471        self.set_http_response(status_code=200)
472
473        sg1 = SecurityGroup(name='sg-1')
474        sg2 = SecurityGroup(name='sg-2')
475
476        vpc_security_groups = [
477            VPCSecurityGroupMembership(self.service_connection, 'active', sg1.name),
478            VPCSecurityGroupMembership(self.service_connection, None, sg2.name)]
479
480        db = self.service_connection.create_dbinstance(
481            'SimCoProd01',
482            10,
483            'db.m1.large',
484            'master',
485            'Password01',
486            param_group='default.mysql5.1',
487            db_subnet_group_name='dbSubnetgroup01',
488            vpc_security_groups=vpc_security_groups)
489
490        self.assert_request_parameters({
491            'Action': 'CreateDBInstance',
492            'AllocatedStorage': 10,
493            'AutoMinorVersionUpgrade': 'true',
494            'DBInstanceClass': 'db.m1.large',
495            'DBInstanceIdentifier': 'SimCoProd01',
496            'DBParameterGroupName': 'default.mysql5.1',
497            'DBSubnetGroupName': 'dbSubnetgroup01',
498            'Engine': 'MySQL5.1',
499            'MasterUsername': 'master',
500            'MasterUserPassword': 'Password01',
501            'Port': 3306,
502            'VpcSecurityGroupIds.member.1': 'sg-1',
503            'VpcSecurityGroupIds.member.2': 'sg-2'
504        }, ignore_params_values=['Version'])
505
506
507class TestRDSOptionGroups(AWSMockServiceTestCase):
508    connection_class = RDSConnection
509
510    def setUp(self):
511        super(TestRDSOptionGroups, self).setUp()
512
513    def default_body(self):
514        return """
515        <DescribeOptionGroupsResponse xmlns="http://rds.amazonaws.com/doc/2013-05-15/">
516          <DescribeOptionGroupsResult>
517            <OptionGroupsList>
518              <OptionGroup>
519                <MajorEngineVersion>11.2</MajorEngineVersion>
520                <OptionGroupName>myoptiongroup</OptionGroupName>
521                <EngineName>oracle-se1</EngineName>
522                <OptionGroupDescription>Test option group</OptionGroupDescription>
523                <Options/>
524              </OptionGroup>
525              <OptionGroup>
526                <MajorEngineVersion>11.2</MajorEngineVersion>
527                <OptionGroupName>default:oracle-se1-11-2</OptionGroupName>
528                <EngineName>oracle-se1</EngineName>
529                <OptionGroupDescription>Default Option Group.</OptionGroupDescription>
530                <Options/>
531              </OptionGroup>
532            </OptionGroupsList>
533          </DescribeOptionGroupsResult>
534          <ResponseMetadata>
535            <RequestId>e4b234d9-84d5-11e1-87a6-71059839a52b</RequestId>
536          </ResponseMetadata>
537        </DescribeOptionGroupsResponse>
538        """
539
540    def test_describe_option_groups(self):
541        self.set_http_response(status_code=200)
542        response = self.service_connection.describe_option_groups()
543        self.assertEqual(len(response), 2)
544        options = response[0]
545        self.assertEqual(options.name, 'myoptiongroup')
546        self.assertEqual(options.description, 'Test option group')
547        self.assertEqual(options.engine_name, 'oracle-se1')
548        self.assertEqual(options.major_engine_version, '11.2')
549        options = response[1]
550        self.assertEqual(options.name, 'default:oracle-se1-11-2')
551        self.assertEqual(options.description, 'Default Option Group.')
552        self.assertEqual(options.engine_name, 'oracle-se1')
553        self.assertEqual(options.major_engine_version, '11.2')
554
555class TestRDSLogFile(AWSMockServiceTestCase):
556    connection_class = RDSConnection
557
558    def setUp(self):
559        super(TestRDSLogFile, self).setUp()
560
561    def default_body(self):
562        return """
563        <DescribeDBLogFilesResponse xmlns="http://rds.amazonaws.com/doc/2013-02-12/">
564          <DescribeDBLogFilesResult>
565            <DescribeDBLogFiles>
566              <DescribeDBLogFilesDetails>
567                <LastWritten>1364403600000</LastWritten>
568                <LogFileName>error/mysql-error-running.log</LogFileName>
569                <Size>0</Size>
570              </DescribeDBLogFilesDetails>
571              <DescribeDBLogFilesDetails>
572                <LastWritten>1364338800000</LastWritten>
573                <LogFileName>error/mysql-error-running.log.0</LogFileName>
574                <Size>0</Size>
575              </DescribeDBLogFilesDetails>
576              <DescribeDBLogFilesDetails>
577                <LastWritten>1364342400000</LastWritten>
578                <LogFileName>error/mysql-error-running.log.1</LogFileName>
579                <Size>0</Size>
580              </DescribeDBLogFilesDetails>
581              <DescribeDBLogFilesDetails>
582                <LastWritten>1364346000000</LastWritten>
583                <LogFileName>error/mysql-error-running.log.2</LogFileName>
584                <Size>0</Size>
585              </DescribeDBLogFilesDetails>
586              <DescribeDBLogFilesDetails>
587                <LastWritten>1364349600000</LastWritten>
588                <LogFileName>error/mysql-error-running.log.3</LogFileName>
589                <Size>0</Size>
590              </DescribeDBLogFilesDetails>
591              <DescribeDBLogFilesDetails>
592                <LastWritten>1364405700000</LastWritten>
593                <LogFileName>error/mysql-error.log</LogFileName>
594                <Size>0</Size>
595              </DescribeDBLogFilesDetails>
596            </DescribeDBLogFiles>
597          </DescribeDBLogFilesResult>
598          <ResponseMetadata>
599            <RequestId>d70fb3b3-9704-11e2-a0db-871552e0ef19</RequestId>
600          </ResponseMetadata>
601        </DescribeDBLogFilesResponse>
602        """
603
604    def test_get_all_logs_simple(self):
605        self.set_http_response(status_code=200)
606        response = self.service_connection.get_all_logs('db1')
607
608        self.assert_request_parameters({
609            'Action': 'DescribeDBLogFiles',
610            'DBInstanceIdentifier': 'db1',
611        }, ignore_params_values=['Version'])
612
613        self.assertEqual(len(response), 6)
614        self.assertTrue(isinstance(response[0], LogFile))
615        self.assertEqual(response[0].log_filename, 'error/mysql-error-running.log')
616        self.assertEqual(response[0].last_written, '1364403600000')
617        self.assertEqual(response[0].size, '0')
618
619    def test_get_all_logs_filtered(self):
620        self.set_http_response(status_code=200)
621        response = self.service_connection.get_all_logs('db_instance_1', max_records=100, marker='error/mysql-error.log', file_size=2000000, filename_contains='error', file_last_written=12345678)
622
623        self.assert_request_parameters({
624            'Action': 'DescribeDBLogFiles',
625            'DBInstanceIdentifier': 'db_instance_1',
626            'MaxRecords': 100,
627            'Marker': 'error/mysql-error.log',
628            'FileSize': 2000000,
629            'FilenameContains': 'error',
630            'FileLastWritten': 12345678,
631        }, ignore_params_values=['Version'])
632
633        self.assertEqual(len(response), 6)
634        self.assertTrue(isinstance(response[0], LogFile))
635        self.assertEqual(response[0].log_filename, 'error/mysql-error-running.log')
636        self.assertEqual(response[0].last_written, '1364403600000')
637        self.assertEqual(response[0].size, '0')
638
639
640class TestRDSLogFileDownload(AWSMockServiceTestCase):
641    connection_class = RDSConnection
642    logfile_sample = """
643??2014-01-26 23:59:00.01 spid54      Microsoft SQL Server 2012 - 11.0.2100.60 (X64)
644
645    Feb 10 2012 19:39:15
646
647    Copyright (c) Microsoft Corporation
648
649    Web Edition (64-bit) on Windows NT 6.1 &lt;X64&gt; (Build 7601: Service Pack 1) (Hypervisor)
650
651
652
6532014-01-26 23:59:00.01 spid54      (c) Microsoft Corporation.
654
6552014-01-26 23:59:00.01 spid54      All rights reserved.
656
6572014-01-26 23:59:00.01 spid54      Server process ID is 2976.
658
6592014-01-26 23:59:00.01 spid54      System Manufacturer: 'Xen', System Model: 'HVM domU'.
660
6612014-01-26 23:59:00.01 spid54      Authentication mode is MIXED.
662
6632014-01-26 23:59:00.01 spid54      Logging SQL Server messages in file 'D:\RDSDBDATA\Log\ERROR'.
664
6652014-01-26 23:59:00.01 spid54      The service account is 'WORKGROUP\AMAZONA-NUQUUMV$'. This is an informational message; no user action is required.
666
6672014-01-26 23:59:00.01 spid54      The error log has been reinitialized. See the previous log for older entries.
668
6692014-01-27 00:00:56.42 spid25s     This instance of SQL Server has been using a process ID of 2976 since 10/21/2013 2:16:50 AM (local) 10/21/2013 2:16:50 AM (UTC). This is an informational message only; no user action is required.
670
6712014-01-27 09:35:15.43 spid71      I/O is frozen on database model. No user action is required. However, if I/O is not resumed promptly, you could cancel the backup.
672
6732014-01-27 09:35:15.44 spid72      I/O is frozen on database msdb. No user action is required. However, if I/O is not resumed promptly, you could cancel the backup.
674
6752014-01-27 09:35:15.44 spid74      I/O is frozen on database rdsadmin. No user action is required. However, if I/O is not resumed promptly, you could cancel the backup.
676
6772014-01-27 09:35:15.44 spid73      I/O is frozen on database master. No user action is required. However, if I/O is not resumed promptly, you could cancel the backup.
678
6792014-01-27 09:35:25.57 spid73      I/O was resumed on database master. No user action is required.
680
6812014-01-27 09:35:25.57 spid74      I/O was resumed on database rdsadmin. No user action is required.
682
6832014-01-27 09:35:25.57 spid71      I/O was resumed on database model. No user action is required.
684
6852014-01-27 09:35:25.57 spid72      I/O was resumed on database msdb. No user action is required.
686    """
687
688    def setUp(self):
689        super(TestRDSLogFileDownload, self).setUp()
690
691    def default_body(self):
692        return """
693<DownloadDBLogFilePortionResponse xmlns="http://rds.amazonaws.com/doc/2013-09-09/">
694  <DownloadDBLogFilePortionResult>
695    <Marker>0:4485</Marker>
696    <LogFileData>%s</LogFileData>
697    <AdditionalDataPending>false</AdditionalDataPending>
698  </DownloadDBLogFilePortionResult>
699  <ResponseMetadata>
700    <RequestId>27143615-87ae-11e3-acc9-fb64b157268e</RequestId>
701  </ResponseMetadata>
702</DownloadDBLogFilePortionResponse>
703        """ % self.logfile_sample
704
705    def test_single_download(self):
706        self.set_http_response(status_code=200)
707        response = self.service_connection.get_log_file('db1', 'foo.log')
708
709        self.assertTrue(isinstance(response, LogFileObject))
710        self.assertEqual(response.marker, '0:4485')
711        self.assertEqual(response.dbinstance_id, 'db1')
712        self.assertEqual(response.log_filename, 'foo.log')
713
714        self.assertEqual(response.data, saxutils.unescape(self.logfile_sample))
715
716        self.assert_request_parameters({
717            'Action': 'DownloadDBLogFilePortion',
718            'DBInstanceIdentifier': 'db1',
719            'LogFileName': 'foo.log',
720        }, ignore_params_values=['Version'])
721
722    def test_multi_args(self):
723        self.set_http_response(status_code=200)
724        response = self.service_connection.get_log_file('db1', 'foo.log', marker='0:4485', number_of_lines=10)
725
726        self.assertTrue(isinstance(response, LogFileObject))
727
728        self.assert_request_parameters({
729            'Action': 'DownloadDBLogFilePortion',
730            'DBInstanceIdentifier': 'db1',
731            'Marker': '0:4485',
732            'NumberOfLines': 10,
733            'LogFileName': 'foo.log',
734        }, ignore_params_values=['Version'])
735
736
737class TestRDSOptionGroupOptions(AWSMockServiceTestCase):
738    connection_class = RDSConnection
739
740    def setUp(self):
741        super(TestRDSOptionGroupOptions, self).setUp()
742
743    def default_body(self):
744        return """
745        <DescribeOptionGroupOptionsResponse xmlns="http://rds.amazonaws.com/doc/2013-05-15/">
746          <DescribeOptionGroupOptionsResult>
747            <OptionGroupOptions>
748              <OptionGroupOption>
749                <MajorEngineVersion>11.2</MajorEngineVersion>
750                <PortRequired>true</PortRequired>
751                <OptionsDependedOn/>
752                <Description>Oracle Enterprise Manager</Description>
753                <DefaultPort>1158</DefaultPort>
754                <Name>OEM</Name>
755                <EngineName>oracle-se1</EngineName>
756                <MinimumRequiredMinorEngineVersion>0.2.v3</MinimumRequiredMinorEngineVersion>
757                <Persistent>false</Persistent>
758                <Permanent>false</Permanent>
759              </OptionGroupOption>
760            </OptionGroupOptions>
761          </DescribeOptionGroupOptionsResult>
762          <ResponseMetadata>
763            <RequestId>d9c8f6a1-84c7-11e1-a264-0b23c28bc344</RequestId>
764          </ResponseMetadata>
765        </DescribeOptionGroupOptionsResponse>
766        """
767
768    def test_describe_option_group_options(self):
769        self.set_http_response(status_code=200)
770        response = self.service_connection.describe_option_group_options()
771        self.assertEqual(len(response), 1)
772        options = response[0]
773        self.assertEqual(options.name, 'OEM')
774        self.assertEqual(options.description, 'Oracle Enterprise Manager')
775        self.assertEqual(options.engine_name, 'oracle-se1')
776        self.assertEqual(options.major_engine_version, '11.2')
777        self.assertEqual(options.min_minor_engine_version, '0.2.v3')
778        self.assertEqual(options.port_required, True)
779        self.assertEqual(options.default_port, 1158)
780        self.assertEqual(options.permanent, False)
781        self.assertEqual(options.persistent, False)
782        self.assertEqual(options.depends_on, [])
783
784
785if __name__ == '__main__':
786    unittest.main()
787
788