open-match.dev/open-match@v1.8.1/examples/functions/golang/backfill/mmf/matchfunction_test.go (about)

     1  // Copyright 2020 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //	http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  package mmf
    15  
    16  import (
    17  	"testing"
    18  
    19  	"github.com/stretchr/testify/require"
    20  	"google.golang.org/protobuf/types/known/anypb"
    21  	"google.golang.org/protobuf/types/known/wrapperspb"
    22  	"open-match.dev/open-match/pkg/pb"
    23  )
    24  
    25  func TestHandleBackfills(t *testing.T) {
    26  	for _, tc := range []struct {
    27  		name              string
    28  		tickets           []*pb.Ticket
    29  		backfills         []*pb.Backfill
    30  		lastMatchId       int
    31  		expectedMatchLen  int
    32  		expectedTicketLen int
    33  		expectedOpenSlots int32
    34  		expectedErr       bool
    35  	}{
    36  		{name: "returns no matches when no backfills specified", expectedMatchLen: 0, expectedTicketLen: 0},
    37  		{name: "returns no matches when no tickets specified", expectedMatchLen: 0, expectedTicketLen: 0},
    38  		{name: "returns a match with open slots decreased", tickets: []*pb.Ticket{{Id: "1"}}, backfills: []*pb.Backfill{withOpenSlots(1)}, expectedMatchLen: 1, expectedTicketLen: 0, expectedOpenSlots: playersPerMatch - 2},
    39  	} {
    40  		testCase := tc
    41  		t.Run(testCase.name, func(t *testing.T) {
    42  			t.Parallel()
    43  
    44  			profile := pb.MatchProfile{Name: "matchProfile"}
    45  			matches, tickets, err := handleBackfills(&profile, testCase.tickets, testCase.backfills, testCase.lastMatchId)
    46  			require.Equal(t, testCase.expectedErr, err != nil)
    47  			require.Equal(t, testCase.expectedTicketLen, len(tickets))
    48  
    49  			if err != nil {
    50  				require.Equal(t, 0, len(matches))
    51  			} else {
    52  				for _, m := range matches {
    53  					require.NotNil(t, m.Backfill)
    54  
    55  					openSlots, err := getOpenSlots(m.Backfill)
    56  					require.NoError(t, err)
    57  					require.Equal(t, testCase.expectedOpenSlots, openSlots)
    58  				}
    59  			}
    60  		})
    61  	}
    62  }
    63  
    64  func TestMakeMatchWithBackfill(t *testing.T) {
    65  	for _, testCase := range []struct {
    66  		name              string
    67  		tickets           []*pb.Ticket
    68  		lastMatchId       int
    69  		expectedOpenSlots int32
    70  		expectedErr       bool
    71  	}{
    72  		{name: "returns an error when length of tickets is greater then playerPerMatch", tickets: []*pb.Ticket{{Id: "1"}, {Id: "2"}, {Id: "3"}, {Id: "4"}, {Id: "5"}}, expectedErr: true},
    73  		{name: "returns an error when length of tickets is equal to playerPerMatch", tickets: []*pb.Ticket{{Id: "1"}, {Id: "2"}, {Id: "3"}, {Id: "4"}}, expectedErr: true},
    74  		{name: "returns an error when no tickets are provided", expectedErr: true},
    75  		{name: "returns a match with backfill", tickets: []*pb.Ticket{{Id: "1"}}, expectedOpenSlots: playersPerMatch - 1},
    76  	} {
    77  		testCase := testCase
    78  		t.Run(testCase.name, func(t *testing.T) {
    79  			t.Parallel()
    80  
    81  			pool := pb.Pool{}
    82  			profile := pb.MatchProfile{Name: "matchProfile"}
    83  			match, err := makeMatchWithBackfill(&profile, &pool, testCase.tickets, testCase.lastMatchId)
    84  			require.Equal(t, testCase.expectedErr, err != nil)
    85  
    86  			if err == nil {
    87  				require.NotNil(t, match)
    88  				require.NotNil(t, match.Backfill)
    89  				require.True(t, match.AllocateGameserver)
    90  				require.Equal(t, "", match.Backfill.Id)
    91  
    92  				openSlots, err := getOpenSlots(match.Backfill)
    93  				require.Nil(t, err)
    94  				require.Equal(t, testCase.expectedOpenSlots, openSlots)
    95  			}
    96  		})
    97  
    98  	}
    99  }
   100  
   101  func TestMakeFullMatches(t *testing.T) {
   102  	for _, testCase := range []struct {
   103  		name              string
   104  		tickets           []*pb.Ticket
   105  		lastMatchId       int
   106  		expectedMatchLen  int
   107  		expectedTicketLen int
   108  	}{
   109  		{name: "returns no matches when there are no tickets", tickets: []*pb.Ticket{}, expectedMatchLen: 0, expectedTicketLen: 0},
   110  		{name: "returns no matches when length of tickets is less then playersPerMatch", tickets: []*pb.Ticket{{Id: "1"}}, expectedMatchLen: 0, expectedTicketLen: 1},
   111  		{name: "returns a match when length of tickets is greater then playersPerMatch", tickets: []*pb.Ticket{{Id: "1"}, {Id: "2"}}, expectedMatchLen: 1, expectedTicketLen: 0},
   112  	} {
   113  		testCase := testCase
   114  		t.Run(testCase.name, func(t *testing.T) {
   115  			t.Parallel()
   116  			profile := pb.MatchProfile{Name: "matchProfile"}
   117  			matches, tickets := makeFullMatches(&profile, testCase.tickets, testCase.lastMatchId)
   118  
   119  			require.Equal(t, testCase.expectedMatchLen, len(matches))
   120  			require.Equal(t, testCase.expectedTicketLen, len(tickets))
   121  
   122  			for _, m := range matches {
   123  				require.Nil(t, m.Backfill)
   124  				require.Equal(t, playersPerMatch, len(m.Tickets))
   125  			}
   126  		})
   127  	}
   128  }
   129  
   130  func withOpenSlots(openSlots int) *pb.Backfill {
   131  	val, err := anypb.New(&wrapperspb.Int32Value{Value: int32(openSlots)})
   132  	if err != nil {
   133  		panic(err)
   134  	}
   135  
   136  	return &pb.Backfill{
   137  		Extensions: map[string]*anypb.Any{
   138  			openSlotsKey: val,
   139  		},
   140  	}
   141  }