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 <X64> (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