Skip to content

Commit 991480b

Browse files
Gerald W. LesterGerald W. Lester
Gerald W. Lester
authored and
Gerald W. Lester
committed
Added inqeuality conditions
1 parent 68e2c8e commit 991480b

File tree

4 files changed

+346
-1
lines changed

4 files changed

+346
-1
lines changed

aws_lambda_powertools/utilities/feature_flags/feature_flags.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ def _match_by_action(action: str, condition_value: Any, context_value: Any) -> b
4444
return False
4545
mapping_by_action = {
4646
schema.RuleAction.EQUALS.value: lambda a, b: a == b,
47+
schema.RuleAction.NOT_EQUALS.value: lambda a, b: a != b,
48+
schema.RuleAction.KEY_GREATER_THAN_VALUE.value: lambda a, b: a > b,
49+
schema.RuleAction.KEY_GREATER_THAN_OR_EQUAL_VALUE.value: lambda a, b: a >= b,
50+
schema.RuleAction.KEY_LESS_THAN_VALUE.value: lambda a, b: a < b,
51+
schema.RuleAction.KEY_LESS_THAN_OR_EQUAL_VALUE.value: lambda a, b: a <= b,
4752
schema.RuleAction.STARTSWITH.value: lambda a, b: a.startswith(b),
4853
schema.RuleAction.ENDSWITH.value: lambda a, b: a.endswith(b),
4954
schema.RuleAction.IN.value: lambda a, b: a in b,

aws_lambda_powertools/utilities/feature_flags/schema.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818

1919
class RuleAction(str, Enum):
2020
EQUALS = "EQUALS"
21+
NOT_EQUALS = "NOT_EQUALS"
22+
KEY_GREATER_THAN_VALUE = "KEY_GREATER_THAN_VALUE"
23+
KEY_GREATER_THAN_OR_EQUAL_VALUE = "KEY_GREATER_THAN_OR_EQUAL_VALUE"
24+
KEY_LESS_THAN_VALUE = "KEY_LESS_THAN_VALUE"
25+
KEY_LESS_THAN_OR_EQUAL_VALUE = "KEY_LESS_THAN_OR_EQUAL_VALUE"
2126
STARTSWITH = "STARTSWITH"
2227
ENDSWITH = "ENDSWITH"
2328
IN = "IN"

docs/utilities/feature_flags.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ The `conditions` block is a list of conditions that contain `action`, `key`, and
450450
}
451451
```
452452

453-
The `action` configuration can have 5 different values: `EQUALS`, `STARTSWITH`, `ENDSWITH`, `IN`, `NOT_IN`.
453+
The `action` configuration can have ten different values: `EQUALS`, `NOT_EQUALS`, `KEY_LESS_THAN_VALUE`, `KEY_LESS_THAN_OR_EQUAL_VALUE`, `KEY_GREATER_THAN_VALUE`, `KEY_GREATER_THAN_OR_EQUAL_VALUE`, `STARTSWITH`, `ENDSWITH`, `IN`, `NOT_IN`.
454454

455455
The `key` and `value` will be compared to the input from the context parameter.
456456

tests/functional/feature_flags/test_feature_flags.py

Lines changed: 335 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,3 +587,338 @@ def test_get_feature_toggle_propagates_access_denied_error(mocker, config):
587587
# THEN raise StoreClientError error
588588
with pytest.raises(StoreClientError, match="AccessDeniedException") as err:
589589
feature_flags.evaluate(name="Foo", default=False)
590+
591+
##
592+
## Inequality test cases
593+
##
594+
595+
# Test not equals
596+
def test_flags_not_eqaul_no_match(mocker, config):
597+
expected_value = False
598+
mocked_app_config_schema = {
599+
"my_feature": {
600+
"default": expected_value,
601+
"rules": {
602+
"tenant id not equals 345345435": {
603+
"when_match": False,
604+
"conditions": [
605+
{
606+
"action": RuleAction.NOT_EQUALS.value,
607+
"key": "tenant_id",
608+
"value": "345345435",
609+
}
610+
],
611+
}
612+
},
613+
}
614+
}
615+
feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config)
616+
toggle = feature_flags.evaluate(name="my_feature", context={"tenant_id": "345345435", "username": "a"}, default=False)
617+
assert toggle == expected_value
618+
619+
def test_flags_not_eqaul_match(mocker, config):
620+
expected_value = True
621+
mocked_app_config_schema = {
622+
"my_feature": {
623+
"default": expected_value,
624+
"rules": {
625+
"tenant id not equals 345345435": {
626+
"when_match": False,
627+
"conditions": [
628+
{
629+
"action": RuleAction.NOT_EQUALS.value,
630+
"key": "tenant_id",
631+
"value": "345345435",
632+
}
633+
],
634+
}
635+
},
636+
}
637+
}
638+
feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config)
639+
toggle = feature_flags.evaluate(name="my_feature", context={"tenant_id": "", "username": "a"}, default=False)
640+
assert toggle == expected_value
641+
642+
643+
# Test less than
644+
def test_flags_less_than_no_match_1(mocker, config):
645+
expected_value = False
646+
mocked_app_config_schema = {
647+
"my_feature": {
648+
"default": expected_value,
649+
"rules": {
650+
"Date less than 2021.10.31": {
651+
"when_match": False,
652+
"conditions": [
653+
{
654+
"action": RuleAction.KEY_LESS_THAN_VALUE.value,
655+
"key": "current_date",
656+
"value": "2021.10.31",
657+
}
658+
],
659+
}
660+
},
661+
}
662+
}
663+
feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config)
664+
toggle = feature_flags.evaluate(name="my_feature", context={"tenant_id": "345345435", "username": "a", "current_date": "2021.12.25"}, default=False)
665+
assert toggle == expected_value
666+
667+
def test_flags_less_than_no_match_2(mocker, config):
668+
expected_value = False
669+
mocked_app_config_schema = {
670+
"my_feature": {
671+
"default": expected_value,
672+
"rules": {
673+
"Date less than 2021.10.31": {
674+
"when_match": False,
675+
"conditions": [
676+
{
677+
"action": RuleAction.KEY_LESS_THAN_VALUE.value,
678+
"key": "current_date",
679+
"value": "2021.10.31",
680+
}
681+
],
682+
}
683+
},
684+
}
685+
}
686+
feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config)
687+
toggle = feature_flags.evaluate(name="my_feature", context={"tenant_id": "345345435", "username": "a", "current_date": "2021.10.31"}, default=False)
688+
assert toggle == expected_value
689+
690+
def test_flags_less_than_match(mocker, config):
691+
expected_value = True
692+
mocked_app_config_schema = {
693+
"my_feature": {
694+
"default": expected_value,
695+
"rules": {
696+
"Date less than 2021.10.31": {
697+
"when_match": False,
698+
"conditions": [
699+
{
700+
"action": RuleAction.KEY_LESS_THAN_VALUE.value,
701+
"key": "current_date",
702+
"value": "2021.10.31",
703+
}
704+
],
705+
}
706+
},
707+
}
708+
}
709+
feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config)
710+
toggle = feature_flags.evaluate(name="my_feature", context={"tenant_id": "345345435", "username": "a", "current_date": "2021.04.01"}, default=False)
711+
assert toggle == expected_value
712+
713+
# Test less than or equal to
714+
def test_flags_less_than_or_equal_no_match(mocker, config):
715+
expected_value = False
716+
mocked_app_config_schema = {
717+
"my_feature": {
718+
"default": expected_value,
719+
"rules": {
720+
"Date less than or equal 2021.10.31": {
721+
"when_match": False,
722+
"conditions": [
723+
{
724+
"action": RuleAction.KEY_LESS_THAN_OR_EQUAL_VALUE.value,
725+
"key": "current_date",
726+
"value": "2021.10.31",
727+
}
728+
],
729+
}
730+
},
731+
}
732+
}
733+
feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config)
734+
toggle = feature_flags.evaluate(name="my_feature", context={"tenant_id": "345345435", "username": "a", "current_date": "2021.12.25"}, default=False)
735+
assert toggle == expected_value
736+
737+
def test_flags_less_than_or_equal_match_1(mocker, config):
738+
expected_value = True
739+
mocked_app_config_schema = {
740+
"my_feature": {
741+
"default": expected_value,
742+
"rules": {
743+
"Date less than or equal 2021.10.31": {
744+
"when_match": False,
745+
"conditions": [
746+
{
747+
"action": RuleAction.KEY_LESS_THAN_OR_EQUAL_VALUE.value,
748+
"key": "current_date",
749+
"value": "2021.10.31",
750+
}
751+
],
752+
}
753+
},
754+
}
755+
}
756+
feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config)
757+
toggle = feature_flags.evaluate(name="my_feature", context={"tenant_id": "345345435", "username": "a", "current_date": "2021.04.01"}, default=False)
758+
assert toggle == expected_value
759+
760+
761+
def test_flags_less_than_or_equal_match_2(mocker, config):
762+
expected_value = True
763+
mocked_app_config_schema = {
764+
"my_feature": {
765+
"default": expected_value,
766+
"rules": {
767+
"Date less than or equal 2021.10.31": {
768+
"when_match": False,
769+
"conditions": [
770+
{
771+
"action": RuleAction.KEY_LESS_THAN_OR_EQUAL_VALUE.value,
772+
"key": "current_date",
773+
"value": "2021.10.31",
774+
}
775+
],
776+
}
777+
},
778+
}
779+
}
780+
feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config)
781+
toggle = feature_flags.evaluate(name="my_feature", context={"tenant_id": "345345435", "username": "a", "current_date": "2021.10.31"}, default=False)
782+
assert toggle == expected_value
783+
784+
# Test greater than
785+
def test_flags_greater_than_no_match_1(mocker, config):
786+
expected_value = False
787+
mocked_app_config_schema = {
788+
"my_feature": {
789+
"default": expected_value,
790+
"rules": {
791+
"Date greater than 2021.10.31": {
792+
"when_match": False,
793+
"conditions": [
794+
{
795+
"action": RuleAction.KEY_GREATER_THAN_VALUE.value,
796+
"key": "current_date",
797+
"value": "2021.10.31",
798+
}
799+
],
800+
}
801+
},
802+
}
803+
}
804+
feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config)
805+
toggle = feature_flags.evaluate(name="my_feature", context={"tenant_id": "345345435", "username": "a", "current_date": "2021.04.01"}, default=False)
806+
assert toggle == expected_value
807+
808+
def test_flags_greater_than_no_match_2(mocker, config):
809+
expected_value = False
810+
mocked_app_config_schema = {
811+
"my_feature": {
812+
"default": expected_value,
813+
"rules": {
814+
"Date greater than 2021.10.31": {
815+
"when_match": False,
816+
"conditions": [
817+
{
818+
"action": RuleAction.KEY_GREATER_THAN_VALUE.value,
819+
"key": "current_date",
820+
"value": "2021.10.31",
821+
}
822+
],
823+
}
824+
},
825+
}
826+
}
827+
feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config)
828+
toggle = feature_flags.evaluate(name="my_feature", context={"tenant_id": "345345435", "username": "a", "current_date": "2021.10.31"}, default=False)
829+
assert toggle == expected_value
830+
831+
def test_flags_greater_than_match(mocker, config):
832+
expected_value = True
833+
mocked_app_config_schema = {
834+
"my_feature": {
835+
"default": expected_value,
836+
"rules": {
837+
"Date greater than 2021.10.31": {
838+
"when_match": False,
839+
"conditions": [
840+
{
841+
"action": RuleAction.KEY_GREATER_THAN_VALUE.value,
842+
"key": "current_date",
843+
"value": "2021.10.31",
844+
}
845+
],
846+
}
847+
},
848+
}
849+
}
850+
feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config)
851+
toggle = feature_flags.evaluate(name="my_feature", context={"tenant_id": "345345435", "username": "a", "current_date": "2021.12.25"}, default=False)
852+
assert toggle == expected_value
853+
854+
# Test greater than or equal to
855+
def test_flags_greater_than_or_equal_no_match(mocker, config):
856+
expected_value = False
857+
mocked_app_config_schema = {
858+
"my_feature": {
859+
"default": expected_value,
860+
"rules": {
861+
"Date greater than or equal 2021.10.31": {
862+
"when_match": False,
863+
"conditions": [
864+
{
865+
"action": RuleAction.KEY_GREATER_THAN_OR_EQUAL_VALUE.value,
866+
"key": "current_date",
867+
"value": "2021.10.31",
868+
}
869+
],
870+
}
871+
},
872+
}
873+
}
874+
feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config)
875+
toggle = feature_flags.evaluate(name="my_feature", context={"tenant_id": "345345435", "username": "a", "current_date": "2021.12.25"}, default=False)
876+
assert toggle == expected_value
877+
878+
def test_flags_greater_than_or_equal_match_1(mocker, config):
879+
expected_value = True
880+
mocked_app_config_schema = {
881+
"my_feature": {
882+
"default": expected_value,
883+
"rules": {
884+
"Date greater than or equal 2021.10.31": {
885+
"when_match": False,
886+
"conditions": [
887+
{
888+
"action": RuleAction.KEY_GREATER_THAN_OR_EQUAL_VALUE.value,
889+
"key": "current_date",
890+
"value": "2021.10.31",
891+
}
892+
],
893+
}
894+
},
895+
}
896+
}
897+
feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config)
898+
toggle = feature_flags.evaluate(name="my_feature", context={"tenant_id": "345345435", "username": "a", "current_date": "2021.04.01"}, default=False)
899+
assert toggle == expected_value
900+
901+
902+
def test_flags_greater_than_or_equal_match_2(mocker, config):
903+
expected_value = True
904+
mocked_app_config_schema = {
905+
"my_feature": {
906+
"default": expected_value,
907+
"rules": {
908+
"Date greater than or equal 2021.10.31": {
909+
"when_match": False,
910+
"conditions": [
911+
{
912+
"action": RuleAction.KEY_GREATER_THAN_OR_EQUAL_VALUE.value,
913+
"key": "current_date",
914+
"value": "2021.10.31",
915+
}
916+
],
917+
}
918+
},
919+
}
920+
}
921+
feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config)
922+
toggle = feature_flags.evaluate(name="my_feature", context={"tenant_id": "345345435", "username": "a", "current_date": "2021.10.31"}, default=False)
923+
assert toggle == expected_value
924+

0 commit comments

Comments
 (0)