github.com/jmbataller/terraform@v0.6.8-0.20151125192640-b7a12e3a580c/builtin/providers/aws/resource_aws_autoscaling_group_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"regexp"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/aws/aws-sdk-go/aws"
    11  	"github.com/aws/aws-sdk-go/aws/awserr"
    12  	"github.com/aws/aws-sdk-go/service/autoscaling"
    13  	"github.com/hashicorp/terraform/helper/resource"
    14  	"github.com/hashicorp/terraform/terraform"
    15  )
    16  
    17  func TestAccAWSAutoScalingGroup_basic(t *testing.T) {
    18  	var group autoscaling.Group
    19  	var lc autoscaling.LaunchConfiguration
    20  
    21  	resource.Test(t, resource.TestCase{
    22  		PreCheck:     func() { testAccPreCheck(t) },
    23  		Providers:    testAccProviders,
    24  		CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy,
    25  		Steps: []resource.TestStep{
    26  			resource.TestStep{
    27  				Config: testAccAWSAutoScalingGroupConfig,
    28  				Check: resource.ComposeTestCheckFunc(
    29  					testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group),
    30  					testAccCheckAWSAutoScalingGroupHealthyCapacity(&group, 2),
    31  					testAccCheckAWSAutoScalingGroupAttributes(&group),
    32  					resource.TestCheckResourceAttr(
    33  						"aws_autoscaling_group.bar", "availability_zones.2487133097", "us-west-2a"),
    34  					resource.TestCheckResourceAttr(
    35  						"aws_autoscaling_group.bar", "name", "foobar3-terraform-test"),
    36  					resource.TestCheckResourceAttr(
    37  						"aws_autoscaling_group.bar", "max_size", "5"),
    38  					resource.TestCheckResourceAttr(
    39  						"aws_autoscaling_group.bar", "min_size", "2"),
    40  					resource.TestCheckResourceAttr(
    41  						"aws_autoscaling_group.bar", "health_check_grace_period", "300"),
    42  					resource.TestCheckResourceAttr(
    43  						"aws_autoscaling_group.bar", "health_check_type", "ELB"),
    44  					resource.TestCheckResourceAttr(
    45  						"aws_autoscaling_group.bar", "desired_capacity", "4"),
    46  					resource.TestCheckResourceAttr(
    47  						"aws_autoscaling_group.bar", "force_delete", "true"),
    48  					resource.TestCheckResourceAttr(
    49  						"aws_autoscaling_group.bar", "termination_policies.0", "OldestInstance"),
    50  					resource.TestCheckResourceAttr(
    51  						"aws_autoscaling_group.bar", "termination_policies.1", "ClosestToNextInstanceHour"),
    52  				),
    53  			},
    54  
    55  			resource.TestStep{
    56  				Config: testAccAWSAutoScalingGroupConfigUpdate,
    57  				Check: resource.ComposeTestCheckFunc(
    58  					testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group),
    59  					testAccCheckAWSLaunchConfigurationExists("aws_launch_configuration.new", &lc),
    60  					resource.TestCheckResourceAttr(
    61  						"aws_autoscaling_group.bar", "desired_capacity", "5"),
    62  					resource.TestCheckResourceAttr(
    63  						"aws_autoscaling_group.bar", "termination_policies.0", "ClosestToNextInstanceHour"),
    64  					testLaunchConfigurationName("aws_autoscaling_group.bar", &lc),
    65  					testAccCheckAutoscalingTags(&group.Tags, "Bar", map[string]interface{}{
    66  						"value":               "bar-foo",
    67  						"propagate_at_launch": true,
    68  					}),
    69  				),
    70  			},
    71  		},
    72  	})
    73  }
    74  
    75  func TestAccAWSAutoScalingGroup_autoGeneratedName(t *testing.T) {
    76  	asgNameRegexp := regexp.MustCompile("^tf-asg-")
    77  
    78  	resource.Test(t, resource.TestCase{
    79  		PreCheck:     func() { testAccPreCheck(t) },
    80  		Providers:    testAccProviders,
    81  		CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy,
    82  		Steps: []resource.TestStep{
    83  			resource.TestStep{
    84  				Config: testAccAWSAutoScalingGroupConfig_autoGeneratedName,
    85  				Check: resource.ComposeTestCheckFunc(
    86  					resource.TestMatchResourceAttr(
    87  						"aws_autoscaling_group.bar", "name", asgNameRegexp),
    88  				),
    89  			},
    90  		},
    91  	})
    92  
    93  }
    94  
    95  func TestAccAWSAutoScalingGroup_tags(t *testing.T) {
    96  	var group autoscaling.Group
    97  
    98  	resource.Test(t, resource.TestCase{
    99  		PreCheck:     func() { testAccPreCheck(t) },
   100  		Providers:    testAccProviders,
   101  		CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy,
   102  		Steps: []resource.TestStep{
   103  			resource.TestStep{
   104  				Config: testAccAWSAutoScalingGroupConfig,
   105  				Check: resource.ComposeTestCheckFunc(
   106  					testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group),
   107  					testAccCheckAutoscalingTags(&group.Tags, "Foo", map[string]interface{}{
   108  						"value":               "foo-bar",
   109  						"propagate_at_launch": true,
   110  					}),
   111  				),
   112  			},
   113  
   114  			resource.TestStep{
   115  				Config: testAccAWSAutoScalingGroupConfigUpdate,
   116  				Check: resource.ComposeTestCheckFunc(
   117  					testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group),
   118  					testAccCheckAutoscalingTagNotExists(&group.Tags, "Foo"),
   119  					testAccCheckAutoscalingTags(&group.Tags, "Bar", map[string]interface{}{
   120  						"value":               "bar-foo",
   121  						"propagate_at_launch": true,
   122  					}),
   123  				),
   124  			},
   125  		},
   126  	})
   127  }
   128  
   129  func TestAccAWSAutoScalingGroup_VpcUpdates(t *testing.T) {
   130  	var group autoscaling.Group
   131  
   132  	resource.Test(t, resource.TestCase{
   133  		PreCheck:     func() { testAccPreCheck(t) },
   134  		Providers:    testAccProviders,
   135  		CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy,
   136  		Steps: []resource.TestStep{
   137  			resource.TestStep{
   138  				Config: testAccAWSAutoScalingGroupConfigWithAZ,
   139  				Check: resource.ComposeTestCheckFunc(
   140  					testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group),
   141  				),
   142  			},
   143  
   144  			resource.TestStep{
   145  				Config: testAccAWSAutoScalingGroupConfigWithVPCIdent,
   146  				Check: resource.ComposeTestCheckFunc(
   147  					testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group),
   148  					testAccCheckAWSAutoScalingGroupAttributesVPCZoneIdentifer(&group),
   149  				),
   150  			},
   151  		},
   152  	})
   153  }
   154  
   155  func TestAccAWSAutoScalingGroup_WithLoadBalancer(t *testing.T) {
   156  	var group autoscaling.Group
   157  
   158  	resource.Test(t, resource.TestCase{
   159  		PreCheck:     func() { testAccPreCheck(t) },
   160  		Providers:    testAccProviders,
   161  		CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy,
   162  		Steps: []resource.TestStep{
   163  			resource.TestStep{
   164  				Config: testAccAWSAutoScalingGroupConfigWithLoadBalancer,
   165  				Check: resource.ComposeTestCheckFunc(
   166  					testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group),
   167  					testAccCheckAWSAutoScalingGroupAttributesLoadBalancer(&group),
   168  				),
   169  			},
   170  		},
   171  	})
   172  }
   173  
   174  func testAccCheckAWSAutoScalingGroupDestroy(s *terraform.State) error {
   175  	conn := testAccProvider.Meta().(*AWSClient).autoscalingconn
   176  
   177  	for _, rs := range s.RootModule().Resources {
   178  		if rs.Type != "aws_autoscaling_group" {
   179  			continue
   180  		}
   181  
   182  		// Try to find the Group
   183  		describeGroups, err := conn.DescribeAutoScalingGroups(
   184  			&autoscaling.DescribeAutoScalingGroupsInput{
   185  				AutoScalingGroupNames: []*string{aws.String(rs.Primary.ID)},
   186  			})
   187  
   188  		if err == nil {
   189  			if len(describeGroups.AutoScalingGroups) != 0 &&
   190  				*describeGroups.AutoScalingGroups[0].AutoScalingGroupName == rs.Primary.ID {
   191  				return fmt.Errorf("AutoScaling Group still exists")
   192  			}
   193  		}
   194  
   195  		// Verify the error
   196  		ec2err, ok := err.(awserr.Error)
   197  		if !ok {
   198  			return err
   199  		}
   200  		if ec2err.Code() != "InvalidGroup.NotFound" {
   201  			return err
   202  		}
   203  	}
   204  
   205  	return nil
   206  }
   207  
   208  func testAccCheckAWSAutoScalingGroupAttributes(group *autoscaling.Group) resource.TestCheckFunc {
   209  	return func(s *terraform.State) error {
   210  		if *group.AvailabilityZones[0] != "us-west-2a" {
   211  			return fmt.Errorf("Bad availability_zones: %#v", group.AvailabilityZones[0])
   212  		}
   213  
   214  		if *group.AutoScalingGroupName != "foobar3-terraform-test" {
   215  			return fmt.Errorf("Bad name: %s", *group.AutoScalingGroupName)
   216  		}
   217  
   218  		if *group.MaxSize != 5 {
   219  			return fmt.Errorf("Bad max_size: %d", *group.MaxSize)
   220  		}
   221  
   222  		if *group.MinSize != 2 {
   223  			return fmt.Errorf("Bad max_size: %d", *group.MinSize)
   224  		}
   225  
   226  		if *group.HealthCheckType != "ELB" {
   227  			return fmt.Errorf("Bad health_check_type,\nexpected: %s\ngot: %s", "ELB", *group.HealthCheckType)
   228  		}
   229  
   230  		if *group.HealthCheckGracePeriod != 300 {
   231  			return fmt.Errorf("Bad health_check_grace_period: %d", *group.HealthCheckGracePeriod)
   232  		}
   233  
   234  		if *group.DesiredCapacity != 4 {
   235  			return fmt.Errorf("Bad desired_capacity: %d", *group.DesiredCapacity)
   236  		}
   237  
   238  		if *group.LaunchConfigurationName == "" {
   239  			return fmt.Errorf("Bad launch configuration name: %s", *group.LaunchConfigurationName)
   240  		}
   241  
   242  		t := &autoscaling.TagDescription{
   243  			Key:               aws.String("Foo"),
   244  			Value:             aws.String("foo-bar"),
   245  			PropagateAtLaunch: aws.Bool(true),
   246  			ResourceType:      aws.String("auto-scaling-group"),
   247  			ResourceId:        group.AutoScalingGroupName,
   248  		}
   249  
   250  		if !reflect.DeepEqual(group.Tags[0], t) {
   251  			return fmt.Errorf(
   252  				"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   253  				group.Tags[0],
   254  				t)
   255  		}
   256  
   257  		return nil
   258  	}
   259  }
   260  
   261  func testAccCheckAWSAutoScalingGroupAttributesLoadBalancer(group *autoscaling.Group) resource.TestCheckFunc {
   262  	return func(s *terraform.State) error {
   263  		if *group.LoadBalancerNames[0] != "foobar-terraform-test" {
   264  			return fmt.Errorf("Bad load_balancers: %#v", group.LoadBalancerNames[0])
   265  		}
   266  
   267  		return nil
   268  	}
   269  }
   270  
   271  func testAccCheckAWSAutoScalingGroupExists(n string, group *autoscaling.Group) resource.TestCheckFunc {
   272  	return func(s *terraform.State) error {
   273  		rs, ok := s.RootModule().Resources[n]
   274  		if !ok {
   275  			return fmt.Errorf("Not found: %s", n)
   276  		}
   277  
   278  		if rs.Primary.ID == "" {
   279  			return fmt.Errorf("No AutoScaling Group ID is set")
   280  		}
   281  
   282  		conn := testAccProvider.Meta().(*AWSClient).autoscalingconn
   283  
   284  		describeGroups, err := conn.DescribeAutoScalingGroups(
   285  			&autoscaling.DescribeAutoScalingGroupsInput{
   286  				AutoScalingGroupNames: []*string{aws.String(rs.Primary.ID)},
   287  			})
   288  
   289  		if err != nil {
   290  			return err
   291  		}
   292  
   293  		if len(describeGroups.AutoScalingGroups) != 1 ||
   294  			*describeGroups.AutoScalingGroups[0].AutoScalingGroupName != rs.Primary.ID {
   295  			return fmt.Errorf("AutoScaling Group not found")
   296  		}
   297  
   298  		*group = *describeGroups.AutoScalingGroups[0]
   299  
   300  		return nil
   301  	}
   302  }
   303  
   304  func testLaunchConfigurationName(n string, lc *autoscaling.LaunchConfiguration) resource.TestCheckFunc {
   305  	return func(s *terraform.State) error {
   306  		rs, ok := s.RootModule().Resources[n]
   307  		if !ok {
   308  			return fmt.Errorf("Not found: %s", n)
   309  		}
   310  
   311  		if *lc.LaunchConfigurationName != rs.Primary.Attributes["launch_configuration"] {
   312  			return fmt.Errorf("Launch configuration names do not match")
   313  		}
   314  
   315  		return nil
   316  	}
   317  }
   318  
   319  func testAccCheckAWSAutoScalingGroupHealthyCapacity(
   320  	g *autoscaling.Group, exp int) resource.TestCheckFunc {
   321  	return func(s *terraform.State) error {
   322  		healthy := 0
   323  		for _, i := range g.Instances {
   324  			if i.HealthStatus == nil {
   325  				continue
   326  			}
   327  			if strings.EqualFold(*i.HealthStatus, "Healthy") {
   328  				healthy++
   329  			}
   330  		}
   331  		if healthy < exp {
   332  			return fmt.Errorf("Expected at least %d healthy, got %d.", exp, healthy)
   333  		}
   334  		return nil
   335  	}
   336  }
   337  
   338  func testAccCheckAWSAutoScalingGroupAttributesVPCZoneIdentifer(group *autoscaling.Group) resource.TestCheckFunc {
   339  	return func(s *terraform.State) error {
   340  		// Grab Subnet Ids
   341  		var subnets []string
   342  		for _, rs := range s.RootModule().Resources {
   343  			if rs.Type != "aws_subnet" {
   344  				continue
   345  			}
   346  			subnets = append(subnets, rs.Primary.Attributes["id"])
   347  		}
   348  
   349  		if group.VPCZoneIdentifier == nil {
   350  			return fmt.Errorf("Bad VPC Zone Identifier\nexpected: %s\ngot nil", subnets)
   351  		}
   352  
   353  		zones := strings.Split(*group.VPCZoneIdentifier, ",")
   354  
   355  		remaining := len(zones)
   356  		for _, z := range zones {
   357  			for _, s := range subnets {
   358  				if z == s {
   359  					remaining--
   360  				}
   361  			}
   362  		}
   363  
   364  		if remaining != 0 {
   365  			return fmt.Errorf("Bad VPC Zone Identifier match\nexpected: %s\ngot:%s", zones, subnets)
   366  		}
   367  
   368  		return nil
   369  	}
   370  }
   371  
   372  const testAccAWSAutoScalingGroupConfig_autoGeneratedName = `
   373  resource "aws_launch_configuration" "foobar" {
   374    image_id = "ami-21f78e11"
   375    instance_type = "t1.micro"
   376  }
   377  
   378  resource "aws_autoscaling_group" "bar" {
   379    availability_zones = ["us-west-2a"]
   380    max_size = 1
   381    min_size = 1
   382    health_check_grace_period = 300
   383    health_check_type = "ELB"
   384    desired_capacity = 1
   385    force_delete = true
   386    termination_policies = ["OldestInstance","ClosestToNextInstanceHour"]
   387  
   388    launch_configuration = "${aws_launch_configuration.foobar.name}"
   389  
   390    tag {
   391      key = "Foo"
   392      value = "foo-bar"
   393      propagate_at_launch = true
   394    }
   395  }
   396  `
   397  
   398  const testAccAWSAutoScalingGroupConfig = `
   399  resource "aws_launch_configuration" "foobar" {
   400    image_id = "ami-21f78e11"
   401    instance_type = "t1.micro"
   402  }
   403  
   404  resource "aws_autoscaling_group" "bar" {
   405    availability_zones = ["us-west-2a"]
   406    name = "foobar3-terraform-test"
   407    max_size = 5
   408    min_size = 2
   409    health_check_grace_period = 300
   410    health_check_type = "ELB"
   411    desired_capacity = 4
   412    force_delete = true
   413    termination_policies = ["OldestInstance","ClosestToNextInstanceHour"]
   414  
   415    launch_configuration = "${aws_launch_configuration.foobar.name}"
   416  
   417    tag {
   418      key = "Foo"
   419      value = "foo-bar"
   420      propagate_at_launch = true
   421    }
   422  }
   423  `
   424  
   425  const testAccAWSAutoScalingGroupConfigUpdate = `
   426  resource "aws_launch_configuration" "foobar" {
   427    image_id = "ami-21f78e11"
   428    instance_type = "t1.micro"
   429  }
   430  
   431  resource "aws_launch_configuration" "new" {
   432    image_id = "ami-21f78e11"
   433    instance_type = "t1.micro"
   434  }
   435  
   436  resource "aws_autoscaling_group" "bar" {
   437    availability_zones = ["us-west-2a"]
   438    name = "foobar3-terraform-test"
   439    max_size = 5
   440    min_size = 2
   441    health_check_grace_period = 300
   442    health_check_type = "ELB"
   443    desired_capacity = 5
   444    force_delete = true
   445    termination_policies = ["ClosestToNextInstanceHour"]
   446  
   447    launch_configuration = "${aws_launch_configuration.new.name}"
   448  
   449    tag {
   450      key = "Bar"
   451      value = "bar-foo"
   452      propagate_at_launch = true
   453    }
   454  }
   455  `
   456  
   457  const testAccAWSAutoScalingGroupConfigWithLoadBalancer = `
   458  resource "aws_vpc" "foo" {
   459    cidr_block = "10.1.0.0/16"
   460  	tags { Name = "tf-asg-test" }
   461  }
   462  
   463  resource "aws_internet_gateway" "gw" {
   464    vpc_id = "${aws_vpc.foo.id}"
   465  }
   466  
   467  resource "aws_subnet" "foo" {
   468  	cidr_block = "10.1.1.0/24"
   469  	vpc_id = "${aws_vpc.foo.id}"
   470  }
   471  
   472  resource "aws_security_group" "foo" {
   473    vpc_id="${aws_vpc.foo.id}"
   474  
   475    ingress {
   476      protocol = "-1"
   477      from_port = 0
   478      to_port = 0
   479      cidr_blocks = ["0.0.0.0/0"]
   480    }
   481  
   482    egress {
   483      protocol = "-1"
   484      from_port = 0
   485      to_port = 0
   486      cidr_blocks = ["0.0.0.0/0"]
   487    }
   488  }
   489  
   490  resource "aws_elb" "bar" {
   491    name = "foobar-terraform-test"
   492    subnets = ["${aws_subnet.foo.id}"]
   493  	security_groups = ["${aws_security_group.foo.id}"]
   494  
   495    listener {
   496      instance_port = 80
   497      instance_protocol = "http"
   498      lb_port = 80
   499      lb_protocol = "http"
   500    }
   501  
   502    health_check {
   503      healthy_threshold = 2
   504      unhealthy_threshold = 2
   505      target = "HTTP:80/"
   506      interval = 5
   507      timeout = 2
   508    }
   509  
   510  	depends_on = ["aws_internet_gateway.gw"]
   511  }
   512  
   513  resource "aws_launch_configuration" "foobar" {
   514    // need an AMI that listens on :80 at boot, this is:
   515    // bitnami-nginxstack-1.6.1-0-linux-ubuntu-14.04.1-x86_64-hvm-ebs-ami-99f5b1a9-3
   516    image_id = "ami-b5b3fc85"
   517    instance_type = "t2.micro"
   518  	security_groups = ["${aws_security_group.foo.id}"]
   519  }
   520  
   521  resource "aws_autoscaling_group" "bar" {
   522    availability_zones = ["${aws_subnet.foo.availability_zone}"]
   523  	vpc_zone_identifier = ["${aws_subnet.foo.id}"]
   524    name = "foobar3-terraform-test"
   525    max_size = 2
   526    min_size = 2
   527    health_check_grace_period = 300
   528    health_check_type = "ELB"
   529    min_elb_capacity = 2
   530    force_delete = true
   531  
   532    launch_configuration = "${aws_launch_configuration.foobar.name}"
   533    load_balancers = ["${aws_elb.bar.name}"]
   534  }
   535  `
   536  
   537  const testAccAWSAutoScalingGroupConfigWithAZ = `
   538  resource "aws_vpc" "default" {
   539    cidr_block = "10.0.0.0/16"
   540    tags {
   541       Name = "terraform-test"
   542    }
   543  }
   544  
   545  resource "aws_subnet" "main" {
   546    vpc_id = "${aws_vpc.default.id}"
   547    cidr_block = "10.0.1.0/24"
   548    availability_zone = "us-west-2a"
   549    tags {
   550       Name = "terraform-test"
   551    }
   552  }
   553  
   554  resource "aws_subnet" "alt" {
   555    vpc_id = "${aws_vpc.default.id}"
   556    cidr_block = "10.0.2.0/24"
   557    availability_zone = "us-west-2b"
   558    tags {
   559       Name = "asg-vpc-thing"
   560    }
   561  }
   562  
   563  resource "aws_launch_configuration" "foobar" {
   564    name = "vpc-asg-test"
   565    image_id = "ami-b5b3fc85"
   566    instance_type = "t2.micro"
   567  }
   568  
   569  resource "aws_autoscaling_group" "bar" {
   570    availability_zones = ["us-west-2a"]
   571    name = "vpc-asg-test"
   572    max_size = 2
   573    min_size = 1
   574    health_check_grace_period = 300
   575    health_check_type = "ELB"
   576    desired_capacity = 1
   577    force_delete = true
   578    termination_policies = ["OldestInstance"]
   579    launch_configuration = "${aws_launch_configuration.foobar.name}"
   580  }
   581  `
   582  
   583  const testAccAWSAutoScalingGroupConfigWithVPCIdent = `
   584  resource "aws_vpc" "default" {
   585    cidr_block = "10.0.0.0/16"
   586    tags {
   587       Name = "terraform-test"
   588    }
   589  }
   590  
   591  resource "aws_subnet" "main" {
   592    vpc_id = "${aws_vpc.default.id}"
   593    cidr_block = "10.0.1.0/24"
   594    availability_zone = "us-west-2a"
   595    tags {
   596       Name = "terraform-test"
   597    }
   598  }
   599  
   600  resource "aws_subnet" "alt" {
   601    vpc_id = "${aws_vpc.default.id}"
   602    cidr_block = "10.0.2.0/24"
   603    availability_zone = "us-west-2b"
   604    tags {
   605       Name = "asg-vpc-thing"
   606    }
   607  }
   608  
   609  resource "aws_launch_configuration" "foobar" {
   610    name = "vpc-asg-test"
   611    image_id = "ami-b5b3fc85"
   612    instance_type = "t2.micro"
   613  }
   614  
   615  resource "aws_autoscaling_group" "bar" {
   616    vpc_zone_identifier = [
   617      "${aws_subnet.main.id}",
   618      "${aws_subnet.alt.id}",
   619    ]
   620    name = "vpc-asg-test"
   621    max_size = 2
   622    min_size = 1
   623    health_check_grace_period = 300
   624    health_check_type = "ELB"
   625    desired_capacity = 1
   626    force_delete = true
   627    termination_policies = ["OldestInstance"]
   628    launch_configuration = "${aws_launch_configuration.foobar.name}"
   629  }
   630  `