...

Source file src/github.com/linkerd/linkerd2/pkg/profiles/proto_test.go

Documentation: github.com/linkerd/linkerd2/pkg/profiles

     1  package profiles
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/emicklei/proto"
     8  	sp "github.com/linkerd/linkerd2/controller/gen/apis/serviceprofile/v1alpha2"
     9  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    10  )
    11  
    12  func TestProtoToServiceProfile(t *testing.T) {
    13  	var (
    14  		namespace     = "myns"
    15  		name          = "mysvc"
    16  		clusterDomain = "mycluster.local"
    17  	)
    18  
    19  	t.Run("rpc", func(t *testing.T) {
    20  		protobuf := `syntax = "proto3";
    21  	
    22  	package emojivoto.v1;
    23  	
    24  	message VoteRequest {
    25  	}
    26  	
    27  	message VotingResult {
    28  		string Shortcode = 1;
    29  		int32 Votes = 2;
    30  	}
    31  	
    32  	service VotingService {
    33  		rpc VotePoop (VoteRequest) returns (VoteResponse);
    34  	}`
    35  
    36  		parser := proto.NewParser(strings.NewReader(protobuf))
    37  
    38  		expectedServiceProfile := sp.ServiceProfile{
    39  			TypeMeta: ServiceProfileMeta,
    40  			ObjectMeta: metav1.ObjectMeta{
    41  				Name:      name + "." + namespace + ".svc." + clusterDomain,
    42  				Namespace: namespace,
    43  			},
    44  			Spec: sp.ServiceProfileSpec{
    45  				Routes: []*sp.RouteSpec{
    46  					{
    47  						Name: "VotePoop",
    48  						Condition: &sp.RequestMatch{
    49  							PathRegex: `/emojivoto\.v1\.VotingService/VotePoop`,
    50  							Method:    "POST",
    51  						},
    52  						IsRetryable: false,
    53  					},
    54  				},
    55  			},
    56  		}
    57  
    58  		actualServiceProfile, err := protoToServiceProfile(parser, namespace, name, clusterDomain)
    59  		if err != nil {
    60  			t.Fatalf("Failed to create ServiceProfile: %v", err)
    61  		}
    62  
    63  		err = ServiceProfileYamlEquals(*actualServiceProfile, expectedServiceProfile)
    64  		if err != nil {
    65  			t.Fatalf("ServiceProfiles are not equal: %v", err)
    66  		}
    67  	})
    68  
    69  	t.Run("rpc unknown idempotency level", func(t *testing.T) {
    70  		protobuf := `syntax = "proto3";
    71  	
    72  	package emojivoto.v1;
    73  	
    74  	message VoteRequest {
    75  	}
    76  	
    77  	message VotingResult {
    78  		string Shortcode = 1;
    79  		int32 Votes = 2;
    80  	}
    81  	
    82  	service VotingService {
    83  		rpc VotePoop (VoteRequest) returns (VoteResponse){
    84  			option idempotency_level = "UNKNOWN";
    85  		};
    86  	}`
    87  
    88  		parser := proto.NewParser(strings.NewReader(protobuf))
    89  
    90  		expectedServiceProfile := sp.ServiceProfile{
    91  			TypeMeta: ServiceProfileMeta,
    92  			ObjectMeta: metav1.ObjectMeta{
    93  				Name:      name + "." + namespace + ".svc." + clusterDomain,
    94  				Namespace: namespace,
    95  			},
    96  			Spec: sp.ServiceProfileSpec{
    97  				Routes: []*sp.RouteSpec{
    98  					{
    99  						Name: "VotePoop",
   100  						Condition: &sp.RequestMatch{
   101  							PathRegex: `/emojivoto\.v1\.VotingService/VotePoop`,
   102  							Method:    "POST",
   103  						},
   104  						IsRetryable: false,
   105  					},
   106  				},
   107  			},
   108  		}
   109  
   110  		actualServiceProfile, err := protoToServiceProfile(parser, namespace, name, clusterDomain)
   111  		if err != nil {
   112  			t.Fatalf("Failed to create ServiceProfile: %v", err)
   113  		}
   114  
   115  		err = ServiceProfileYamlEquals(*actualServiceProfile, expectedServiceProfile)
   116  		if err != nil {
   117  			t.Fatalf("ServiceProfiles are not equal: %v", err)
   118  		}
   119  	})
   120  
   121  	t.Run("rpc idempotent", func(t *testing.T) {
   122  		protobuf := `syntax = "proto3";
   123  	
   124  	package emojivoto.v1;
   125  	
   126  	message VoteRequest {
   127  	}
   128  	
   129  	message VotingResult {
   130  		string Shortcode = 1;
   131  		int32 Votes = 2;
   132  	}
   133  	
   134  	service VotingService {
   135  		rpc VotePoop (VoteRequest) returns (VoteResponse){
   136  			option idempotency_level = "IDEMPOTENT";
   137  		};
   138  	}`
   139  
   140  		parser := proto.NewParser(strings.NewReader(protobuf))
   141  
   142  		expectedServiceProfile := sp.ServiceProfile{
   143  			TypeMeta: ServiceProfileMeta,
   144  			ObjectMeta: metav1.ObjectMeta{
   145  				Name:      name + "." + namespace + ".svc." + clusterDomain,
   146  				Namespace: namespace,
   147  			},
   148  			Spec: sp.ServiceProfileSpec{
   149  				Routes: []*sp.RouteSpec{
   150  					{
   151  						Name: "VotePoop",
   152  						Condition: &sp.RequestMatch{
   153  							PathRegex: `/emojivoto\.v1\.VotingService/VotePoop`,
   154  							Method:    "POST",
   155  						},
   156  						IsRetryable: true,
   157  					},
   158  				},
   159  			},
   160  		}
   161  
   162  		actualServiceProfile, err := protoToServiceProfile(parser, namespace, name, clusterDomain)
   163  		if err != nil {
   164  			t.Fatalf("Failed to create ServiceProfile: %v", err)
   165  		}
   166  
   167  		err = ServiceProfileYamlEquals(*actualServiceProfile, expectedServiceProfile)
   168  		if err != nil {
   169  			t.Fatalf("ServiceProfiles are not equal: %v", err)
   170  		}
   171  	})
   172  
   173  	t.Run("rpc no side effects", func(t *testing.T) {
   174  		protobuf := `syntax = "proto3";
   175  	
   176  	package emojivoto.v1;
   177  	
   178  	message VoteRequest {
   179  	}
   180  	
   181  	message VotingResult {
   182  		string Shortcode = 1;
   183  		int32 Votes = 2;
   184  	}
   185  	
   186  	service VotingService {
   187  		rpc VotePoop (VoteRequest) returns (VoteResponse){
   188  			option (idempotency_level) = "NO_SIDE_EFFECTS";
   189  		};
   190  	}`
   191  
   192  		parser := proto.NewParser(strings.NewReader(protobuf))
   193  
   194  		expectedServiceProfile := sp.ServiceProfile{
   195  			TypeMeta: ServiceProfileMeta,
   196  			ObjectMeta: metav1.ObjectMeta{
   197  				Name:      name + "." + namespace + ".svc." + clusterDomain,
   198  				Namespace: namespace,
   199  			},
   200  			Spec: sp.ServiceProfileSpec{
   201  				Routes: []*sp.RouteSpec{
   202  					{
   203  						Name: "VotePoop",
   204  						Condition: &sp.RequestMatch{
   205  							PathRegex: `/emojivoto\.v1\.VotingService/VotePoop`,
   206  							Method:    "POST",
   207  						},
   208  						IsRetryable: true,
   209  					},
   210  				},
   211  			},
   212  		}
   213  
   214  		actualServiceProfile, err := protoToServiceProfile(parser, namespace, name, clusterDomain)
   215  		if err != nil {
   216  			t.Fatalf("Failed to create ServiceProfile: %v", err)
   217  		}
   218  
   219  		err = ServiceProfileYamlEquals(*actualServiceProfile, expectedServiceProfile)
   220  		if err != nil {
   221  			t.Fatalf("ServiceProfiles are not equal: %v", err)
   222  		}
   223  	})
   224  }
   225  

View as plain text