<commit_before>/*
 * Minio Cloud Storage, (C) 2018 Minio, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cmd

import (
	"fmt"
	"reflect"
	"testing"

	"github.com/minio/minio/pkg/ellipses"
)

// Tests create endpoints with ellipses and without.
func TestCreateServerEndpoints(t *testing.T) {
	testCases := []struct {
		serverAddr string
		args       []string
		success    bool
	}{
		// Invalid input.
		{"", []string{}, false},
		// Range cannot be negative.
		{":9000", []string{"/export1{-1...1}"}, false},
		// Range cannot start bigger than end.
		{":9000", []string{"/export1{64...1}"}, false},
		// Range can only be numeric.
		{":9000", []string{"/export1{a...z}"}, false},
		// Duplicate disks not allowed.
		{":9000", []string{"/export1{1...32}", "/export1{1...32}"}, false},
		// Same host cannot export same disk on two ports - special case localhost.
		{":9001", []string{"http://localhost:900{1...2}/export{1...64}"}, false},

		// Valid inputs.
		{":9000", []string{"/export1"}, true},
		{":9000", []string{"/export1", "/export2", "/export3", "/export4"}, true},
		{":9000", []string{"/export1{1...64}"}, true},
		{":9000", []string{"/export1{01...64}"}, true},
		{":9000", []string{"/export1{1...32}", "/export1{33...64}"}, true},
		{":9001", []string{"http://localhost:9001/export{1...64}"}, true},
		{":9001", []string{"http://localhost:9001/export{01...64}"}, true},
	}

	for i, testCase := range testCases {
		_, _, _, _, _, err := createServerEndpoints(testCase.serverAddr, testCase.args...)
		if err != nil && testCase.success {
			t.Errorf("Test %d: Expected success but failed instead %s", i+1, err)
		}
		if err == nil && !testCase.success {
			t.Errorf("Test %d: Expected failure but passed instead", i+1)
		}
	}
}

// Test tests calculating set indexes.
func TestGetSetIndexes(t *testing.T) {
	testCases := []struct {
		args       []string
		totalSizes []uint64
		indexes    [][]uint64
		success    bool
	}{
		// Invalid inputs.
		{
			[]string{"data{1...27}"},
			[]uint64{27},
			nil,
			false,
		},
		// Valid inputs.
		{
			[]string{"data{1...64}"},
			[]uint64{64},
			[][]uint64{{16, 16, 16, 16}},
			true,
		},
		{
			[]string{"data{1...24}"},
			[]uint64{24},
			[][]uint64{{12, 12}},
			true,
		},
		{
			[]string{"data/controller{1...11}/export{1...8}"},
			[]uint64{88},
			[][]uint64{{8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}},
			true,
		},
		{
			[]string{"data{1...4}"},
			[]uint64{4},
			[][]uint64{{4}},
			true,
		},
	}

	for i, testCase := range testCases {
		t.Run(fmt.Sprintf("Test%d", i+1), func(t *testing.T) {
			gotIndexes, err := getSetIndexes(testCase.args, testCase.totalSizes)
			if err != nil && testCase.success {
				t.Errorf("Expected success but failed instead %s", err)
			}
			if err == nil && !testCase.success {
				t.Errorf("Expected failure but passed instead")
			}
			if !reflect.DeepEqual(testCase.indexes, gotIndexes) {
				t.Errorf("Expected %v, got %v", testCase.indexes, gotIndexes)
			}
		})<commit_msg>Add unit tests for endpoint-ellipses.go (#5681)<commit_after>/*
 * Minio Cloud Storage, (C) 2018 Minio, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cmd

import (
	"fmt"
	"reflect"
	"testing"

	"github.com/minio/minio/pkg/ellipses"
)

// Tests create endpoints with ellipses and without.
func TestCreateServerEndpoints(t *testing.T) {
	testCases := []struct {
		serverAddr string
		args       []string
		success    bool
	}{
		// Invalid input.
		{"", []string{}, false},
		// Range cannot be negative.
		{":9000", []string{"/export1{-1...1}"}, false},
		// Range cannot start bigger than end.
		{":9000", []string{"/export1{64...1}"}, false},
		// Range can only be numeric.
		{":9000", []string{"/export1{a...z}"}, false},
		// Duplicate disks not allowed.
		{":9000", []string{"/export1{1...32}", "/export1{1...32}"}, false},
		// Same host cannot export same disk on two ports - special case localhost.
		{":9001", []string{"http://localhost:900{1...2}/export{1...64}"}, false},

		// Valid inputs.
		{":9000", []string{"/export1"}, true},
		{":9000", []string{"/export1", "/export2", "/export3", "/export4"}, true},
		{":9000", []string{"/export1{1...64}"}, true},
		{":9000", []string{"/export1{01...64}"}, true},
		{":9000", []string{"/export1{1...32}", "/export1{33...64}"}, true},
		{":9001", []string{"http://localhost:9001/export{1...64}"}, true},
		{":9001", []string{"http://localhost:9001/export{01...64}"}, true},
	}

	for i, testCase := range testCases {
		_, _, _, _, _, err := createServerEndpoints(testCase.serverAddr, testCase.args...)
		if err != nil && testCase.success {
			t.Errorf("Test %d: Expected success but failed instead %s", i+1, err)
		}
		if err == nil && !testCase.success {
			t.Errorf("Test %d: Expected failure but passed instead", i+1)
		}
	}
}

func TestGetDivisibleSize(t *testing.T) {
	testCases := []struct {
		totalSizes []uint64
		result     uint64
	}{{[]uint64{24, 32, 16}, 8},
		{[]uint64{32, 8, 4}, 4},
		{[]uint64{8, 8, 8}, 8},
		{[]uint64{24}, 24},
	}
	for i, testCase := range testCases {
		t.Run(fmt.Sprintf("Test%d", i+1), func(t *testing.T) {
			gotGCD := getDivisibleSize(testCase.totalSizes)
			if testCase.result != gotGCD {
				t.Errorf("Expected %v, got %v", testCase.result, gotGCD)
			}
		})
	}
}

// Test tests calculating set indexes.
func TestGetSetIndexes(t *testing.T) {
	testCases := []struct {
		args       []string
		totalSizes []uint64
		indexes    [][]uint64
		success    bool
	}{
		// Invalid inputs.
		{
			[]string{"data{1...27}"},
			[]uint64{27},
			nil,
			false,
		},
		{
			[]string{"data{1...3}"},
			[]uint64{3},
			nil,
			false,
		},
		{
			[]string{"data/controller1/export{1...2}, data/controller2/export{1...4}, data/controller3/export{1...8}"},
			[]uint64{2, 4, 8},
			nil,
			false,
		},
		// Valid inputs.
		{
			[]string{"data/controller1/export{1...4}, data/controller2/export{1...8}, data/controller3/export{1...12}"},
			[]uint64{4, 8, 12},
			[][]uint64{{4}, {4, 4}, {4, 4, 4}},
			true,
		},
		{
			[]string{"data{1...64}"},
			[]uint64{64},
			[][]uint64{{16, 16, 16, 16}},
			true,
		},
		{
			[]string{"data{1...24}"},
			[]uint64{24},
			[][]uint64{{12, 12}},
			true,
		},
		{
			[]string{"data/controller{1...11}/export{1...8}"},
			[]uint64{88},
			[][]uint64{{8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}},
			true,
		},
		{
			[]string{"data{1...4}"},
			[]uint64{4},
			[][]uint64{{4}},
			true,
		},
		{
			[]string{"data/controller1/export{1...10}, data/controller2/export{1...10}, data/controller3/export{1...10}"},
			[]uint64{10, 10, 10},
			[][]uint64{{10}, {10}, {10}},
			true,
		},
	}

	for i, testCase := range testCases {
		t.Run(fmt.Sprintf("Test%d", i+1), func(t *testing.T) {
			gotIndexes, err := getSetIndexes(testCase.args, testCase.totalSizes)
			if err != nil && testCase.success {
				t.Errorf("Expected success but failed instead %s", err)
			}
			if err == nil && !testCase.success {
				t.Errorf("Expected failure but passed instead")
			}
			if !reflect.DeepEqual(testCase.indexes, gotIndexes) {
				t.Errorf("Expected %v, got %v", testCase.indexes, gotIndexes)
			}
		})
{'fraction_non_alphanumeric': 0.2116545521744487, 'fraction_numerical': 0.06061352716520882, 'mean_word_length': 3.288431061806656, 'pattern_counts': {'":': 24, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6485298', 'n_tokens_mistral': 3440, 'n_tokens_neox': 2917, 'n_words': 731}