text: """
  Test for environment variable handling
  """
  
  from parameterized import parameterized, param
  from unittest import TestCase
  from unittest.mock import patch
  from samcli.local.lambdafn.env_vars import EnvironmentVariables
  
  
  class TestEnvironmentVariables_init(TestCase):
      def test_must_initialize_with_empty_values(self):
  
          memory = 123
          timeout = 10
          handler = "handler"
  
          environ = EnvironmentVariables()
          environ.memory = memory
          environ.timeout = timeout
          environ.handler = handler
  
          self.assertEqual(environ.memory, memory)
          self.assertEqual(environ.timeout, timeout)
          self.assertEqual(environ.handler, handler)
  
      def test_must_initialize_values_with_required_values(self):
          memory = 123
          timeout = 10
          handler = "handler"
          name = "function_name"
          environ = EnvironmentVariables(name, memory, timeout, handler)
          self.assertEqual(environ.name, name)
          self.assertEqual(environ.memory, memory)
          self.assertEqual(environ.timeout, timeout)
          self.assertEqual(environ.handler, handler)
          self.assertEqual(environ.variables, {})
          self.assertEqual(environ.shell_env_values, {})
          self.assertEqual(environ.override_values, {})
          self.assertEqual(environ.aws_creds, {})
  
      def test_must_initialize_with_optional_values(self):
          name = "function_name"
          memory = 123
          timeout = 10
          handler = "handler"
          variables = {"a": "b"}
          shell_values = {"c": "d"}
          overrides = {"e": "f"}
          aws_creds = {"g": "h"}
  
          environ = EnvironmentVariables(
              name,
              memory,
              timeout,
              handler,
              variables=variables,
              shell_env_values=shell_values,
              override_values=overrides,
              aws_creds=aws_creds,
          )
  
          self.assertEqual(environ.variables, {"a": "b"})
          self.assertEqual(environ.shell_env_values, {"c": "d"})
          self.assertEqual(environ.override_values, {"e": "f"})
          self.assertEqual(environ.aws_creds, {"g": "h"})
  
  
  class TestEnvironmentVariables_resolve(TestCase):
      def setUp(self):
          self.name = "function_name"
          self.memory = 1024
          self.timeout = 123
          self.handler = "handler"
  
          self.aws_creds = {
              "region": "some region",
              "key": "some key",
              "secret": "some other secret",
              "sessiontoken": "some other token",
          }
  
          self.variables = {
              "variable1": 1,
              "variable2": "mystring",
              "list_var": [1, 2, 3],
              "dict_var": {"a": {"b": "c"}},
              "none_var": None,
              "true_var": True,
              "false_var": False,
              # We should be able to override AWS_*  values
              "AWS_DEFAULT_REGION": "user-specified-region",
          }
  
          self.shell_env = {
              # This variable is not defined in self.variables. So won't show up in resutlt
              "myothervar": "somevalue",
              "variable1": "variable1 value from shell_env",
          }
  
          self.override = {
              # This variable is not defined in self.variables. So won't show up in resutlt
              "unknown_var": "newvalue",
              "variable1": "variable1 value from overrides",
              "list_var": "list value coming from overrides",
          }
  
      def test_with_no_additional_variables(self):
          """
          Test assuming user has *not* passed any environment variables. Only AWS variables should be setup
          """
  
          expected = {
              "AWS_SAM_LOCAL": "true",
              "AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "1024",
              "AWS_LAMBDA_FUNCTION_TIMEOUT": "123",
              "AWS_LAMBDA_FUNCTION_HANDLER": "handler",
              "AWS_LAMBDA_FUNCTION_NAME": self.name,
              "AWS_LAMBDA_FUNCTION_VERSION": "$LATEST",
              "AWS_LAMBDA_LOG_GROUP_NAME": f"aws/lambda/{self.name}",
              "AWS_LAMBDA_LOG_STREAM_NAME": "$LATEST",
              "AWS_ACCOUNT_ID": "123456789012",
              "AWS_REGION": "some region",
              "AWS_DEFAULT_REGION": "some region",
              "AWS_ACCESS_KEY_ID": "some key",
              "AWS_SECRET_ACCESS_KEY": "some other secret",
              "AWS_SESSION_TOKEN": "some other token",
          }
  
          environ = EnvironmentVariables(self.name, self.memory, self.timeout, self.handler, aws_creds=self.aws_creds)
  
          result = environ.resolve()
  
          # With no additional environment variables, resolve() should just return all AWS variables
          self.assertEqual(result, expected)
  
      def test_with_only_default_values_for_variables(self):
          """
          Given only environment variable values, without any shell env values or overridden values
          """
  
          expected = {
              "AWS_SAM_LOCAL": "true",
              "AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "1024",
              "AWS_LAMBDA_FUNCTION_TIMEOUT": "123",
              "AWS_LAMBDA_FUNCTION_HANDLER": "handler",
              "AWS_LAMBDA_FUNCTION_NAME": self.name,
              "AWS_LAMBDA_FUNCTION_VERSION": "$LATEST",
              "AWS_LAMBDA_LOG_GROUP_NAME": f"aws/lambda/{self.name}",
              "AWS_LAMBDA_LOG_STREAM_NAME": "$LATEST",
              "AWS_ACCOUNT_ID": "123456789012",
              "AWS_REGION": "us-east-1",
              "AWS_ACCESS_KEY_ID": "defaultkey",
              "AWS_SECRET_ACCESS_KEY": "defaultsecret",
              # This value is coming from user passed environment variable
              "AWS_DEFAULT_REGION": "user-specified-region",
              "variable1": "1",
              "variable2": "mystring",
              "list_var": "",
              "dict_var": "",
              "none_var": "",
              "true_var": "true",
              "false_var": "false",
          }
  
          environ = EnvironmentVariables(self.name, self.memory, self.timeout, self.handler, variables=self.variables)
  
          self.assertEqual(environ.resolve(), expected)
  
      def test_with_shell_env_value(self):
          """
          Given values for the variables from shell environment
          """
  
          expected = {
              "AWS_SAM_LOCAL": "true",
              "AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "1024",
              "AWS_LAMBDA_FUNCTION_TIMEOUT": "123",
              "AWS_LAMBDA_FUNCTION_HANDLER": "handler",
              "AWS_LAMBDA_FUNCTION_NAME": self.name,
              "AWS_LAMBDA_FUNCTION_VERSION": "$LATEST",
              "AWS_LAMBDA_LOG_GROUP_NAME": f"aws/lambda/{self.name}",
              "AWS_LAMBDA_LOG_STREAM_NAME": "$LATEST",
              "AWS_ACCOUNT_ID": "123456789012",
              "AWS_REGION": "us-east-1",
              "AWS_ACCESS_KEY_ID": "defaultkey",
              "AWS_SECRET_ACCESS_KEY": "defaultsecret",
              # This value is coming from user passed environment variable
              "AWS_DEFAULT_REGION": "user-specified-region",
              # Value coming from the shell
              "variable1": "variable1 value from shell_env",
              "variable2": "mystring",
              "list_var": "",
              "dict_var": "",
              "none_var": "",
              "true_var": "true",
              "false_var": "false",
          }
  
          environ = EnvironmentVariables(
              self.name,
              self.memory,
              self.timeout,
              self.handler,
              variables=self.variables,
              shell_env_values=self.shell_env,
          )
  
          self.assertEqual(environ.resolve(), expected)
  
      def test_with_overrides_value(self):
          """
          Given values for the variables from user specified overrides
          """
  
          expected = {
              "AWS_SAM_LOCAL": "true",
              "AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "1024",
              "AWS_LAMBDA_FUNCTION_TIMEOUT": "123",
              "AWS_LAMBDA_FUNCTION_HANDLER": "handler",
              "AWS_LAMBDA_FUNCTION_NAME": self.name,
              "AWS_LAMBDA_FUNCTION_VERSION": "$LATEST",
              "AWS_LAMBDA_LOG_GROUP_NAME": f"aws/lambda/{self.name}",
              "AWS_LAMBDA_LOG_STREAM_NAME": "$LATEST",
              "AWS_ACCOUNT_ID": "123456789012",
              "AWS_REGION": "us-east-1",
              "AWS_ACCESS_KEY_ID": "defaultkey",
              "AWS_SECRET_ACCESS_KEY": "defaultsecret",
              # This value is coming from user passed environment variable
              "AWS_DEFAULT_REGION": "user-specified-region",
              "variable2": "mystring",
              # Value coming from the overrides
              "variable1": "variable1 value from overrides",
              "list_var": "list value coming from overrides",
              "dict_var": "",
              "none_var": "",
              "true_var": "true",
              "false_var": "false",
          }
  
          environ = EnvironmentVariables(
              self.name,
              self.memory,
              self.timeout,
              self.handler,
              variables=self.variables,
              shell_env_values=self.shell_env,
              override_values=self.override,
          )
  
          self.assertEqual(environ.resolve(), expected)
  
  
  class TestEnvironmentVariables_get_aws_variables(TestCase):
      def setUp(self):
          self.name = "function_name"
          self.memory = 1024
          self.timeout = 123
          self.handler = "handler"
  
          self.aws_creds = {
              "region": "some region",
              "key": "some key",
              "secret": "some other secret",
              "sessiontoken": "some other token",
          }
  
      def test_must_work_with_overridden_aws_creds(self):
  
          expected = {
              "AWS_SAM_LOCAL": "true",
              "AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "1024",
              "AWS_LAMBDA_FUNCTION_TIMEOUT": "123",
              "AWS_LAMBDA_FUNCTION_HANDLER": "handler",
              "AWS_LAMBDA_FUNCTION_NAME": self.name,
              "AWS_LAMBDA_FUNCTION_VERSION": "$LATEST",
              "AWS_REGION": "some region",
              "AWS_DEFAULT_REGION": "some region",
              "AWS_ACCESS_KEY_ID": "some key",
              "AWS_SECRET_ACCESS_KEY": "some other secret",
              "AWS_LAMBDA_LOG_GROUP_NAME": f"aws/lambda/{self.name}",
              "AWS_LAMBDA_LOG_STREAM_NAME": "$LATEST",
              "AWS_ACCOUNT_ID": "123456789012",
              "AWS_SESSION_TOKEN": "some other token",
          }
  
          environ = EnvironmentVariables(self.name, self.memory, self.timeout, self.handler, aws_creds=self.aws_creds)
  
          self.assertEqual(expected, environ._get_aws_variables())
  
      def test_must_work_without_any_aws_creds(self):
  
          expected = {
              "AWS_SAM_LOCAL": "true",
              "AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "1024",
              "AWS_LAMBDA_FUNCTION_TIMEOUT": "123",
              "AWS_LAMBDA_FUNCTION_HANDLER": "handler",
              "AWS_LAMBDA_FUNCTION_NAME": self.name,
              "AWS_LAMBDA_FUNCTION_VERSION": "$LATEST",
              "AWS_LAMBDA_LOG_GROUP_NAME": f"aws/lambda/{self.name}",
              "AWS_LAMBDA_LOG_STREAM_NAME": "$LATEST",
              "AWS_ACCOUNT_ID": "123456789012",
              # Default values assigned to these variables
              "AWS_REGION": "us-east-1",
              "AWS_DEFAULT_REGION": "us-east-1",
              "AWS_ACCESS_KEY_ID": "defaultkey",
              "AWS_SECRET_ACCESS_KEY": "defaultsecret",
          }
  
          environ = EnvironmentVariables(self.name, self.memory, self.timeout, self.handler)
          self.assertEqual(expected, environ._get_aws_variables())
  
      def test_must_work_with_partial_aws_creds(self):
  
          creds = {"region": "some other region", "sessiontoken": "my awesome token"}
  
          expected = {
              "AWS_SAM_LOCAL": "true",
              "AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "1024",
              "AWS_LAMBDA_FUNCTION_TIMEOUT": "123",
              "AWS_LAMBDA_FUNCTION_HANDLER": "handler",
              "AWS_LAMBDA_FUNCTION_NAME": self.name,
              "AWS_LAMBDA_FUNCTION_VERSION": "$LATEST",
              "AWS_LAMBDA_LOG_GROUP_NAME": f"aws/lambda/{self.name}",
              "AWS_LAMBDA_LOG_STREAM_NAME": "$LATEST",
              "AWS_ACCOUNT_ID": "123456789012",
              # Values from the input creds
              "AWS_REGION": "some other region",
              "AWS_DEFAULT_REGION": "some other region",
              "AWS_SESSION_TOKEN": "my awesome token",
              # These variables still get the default value
              "AWS_ACCESS_KEY_ID": "defaultkey",
              "AWS_SECRET_ACCESS_KEY": "defaultsecret",
          }
  
          environ = EnvironmentVariables(self.name, self.memory, self.timeout, self.handler, aws_creds=creds)
          self.assertEqual(expected, environ._get_aws_variables())
  
  
  class TestEnvironmentVariables_stringify_value(TestCase):
      def setUp(self):
  
          self.environ = EnvironmentVariables(1024, 10, "handler")
  
      @parameterized.expand([param([1, 2, 3]), param({"a": {"b": "c"}}), param(("this", "is", "tuple")), param(None)])
      def test_must_replace_non_scalar_with_blank_values(self, input):
          self.assertEqual("", self.environ._stringify_value(input))
  
      @parameterized.expand(
          [
              (True, "true"),
              (False, "false"),
              (1234, "1234"),
              (3.14, "3.14"),
              ("mystring\xe0", "mystring\xe0"),
              ("mystring", "mystring"),
          ]
      )
      def test_must_stringify(self, input, expected):
          self.assertEqual(expected, self.environ._stringify_value(input))
  
  
  class TestEnvironmentVariables_add_lambda_event_body(TestCase):
      def test_must_add_proper_variable(self):
  
          value = "foobar"
  
          environ = EnvironmentVariables()
          environ.add_lambda_event_body(value)
  
          self.assertEqual(environ.variables.get("AWS_LAMBDA_EVENT_BODY"), value)
  