github.com/segmentio/kafka-go@v0.4.48-0.20240318174348-3f6244eb34fd/createtopics_test.go (about)

     1  package kafka
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"context"
     7  	"errors"
     8  	"net"
     9  	"reflect"
    10  	"strconv"
    11  	"testing"
    12  )
    13  
    14  func TestConnCreateTopics(t *testing.T) {
    15  	topic1 := makeTopic()
    16  	topic2 := makeTopic()
    17  
    18  	conn, err := DialContext(context.Background(), "tcp", "localhost:9092")
    19  	if err != nil {
    20  		t.Fatal(err)
    21  	}
    22  
    23  	defer func() {
    24  		err := conn.Close()
    25  		if err != nil {
    26  			t.Fatalf("failed to close connection: %v", err)
    27  		}
    28  	}()
    29  
    30  	controller, _ := conn.Controller()
    31  
    32  	controllerConn, err := Dial("tcp", net.JoinHostPort(controller.Host, strconv.Itoa(controller.Port)))
    33  	if err != nil {
    34  		t.Fatal(err)
    35  	}
    36  	defer controllerConn.Close()
    37  
    38  	err = controllerConn.CreateTopics(TopicConfig{
    39  		Topic:             topic1,
    40  		NumPartitions:     1,
    41  		ReplicationFactor: 1,
    42  	})
    43  	if err != nil {
    44  		t.Fatalf("unexpected error creating topic: %s", err.Error())
    45  	}
    46  
    47  	err = controllerConn.CreateTopics(TopicConfig{
    48  		Topic:             topic1,
    49  		NumPartitions:     1,
    50  		ReplicationFactor: 1,
    51  	})
    52  
    53  	// Duplicate topic should not return an error
    54  	if err != nil {
    55  		t.Fatalf("unexpected error creating duplicate topic topic: %v", err)
    56  	}
    57  
    58  	err = controllerConn.CreateTopics(
    59  		TopicConfig{
    60  			Topic:             topic1,
    61  			NumPartitions:     1,
    62  			ReplicationFactor: 1,
    63  		},
    64  		TopicConfig{
    65  			Topic:             topic2,
    66  			NumPartitions:     1,
    67  			ReplicationFactor: 1,
    68  		},
    69  		TopicConfig{
    70  			Topic:             topic2,
    71  			NumPartitions:     1,
    72  			ReplicationFactor: 1,
    73  		},
    74  	)
    75  
    76  	if err == nil {
    77  		t.Fatal("CreateTopics should have returned an error for invalid requests")
    78  	}
    79  
    80  	if !errors.Is(err, InvalidRequest) {
    81  		t.Fatalf("expected invalid request: %v", err)
    82  	}
    83  
    84  	deleteTopic(t, topic1)
    85  }
    86  
    87  func TestClientCreateTopics(t *testing.T) {
    88  	const (
    89  		topic1 = "client-topic-1"
    90  		topic2 = "client-topic-2"
    91  		topic3 = "client-topic-3"
    92  	)
    93  
    94  	client, shutdown := newLocalClient()
    95  	defer shutdown()
    96  
    97  	config := []ConfigEntry{{
    98  		ConfigName:  "retention.ms",
    99  		ConfigValue: "3600000",
   100  	}}
   101  
   102  	res, err := client.CreateTopics(context.Background(), &CreateTopicsRequest{
   103  		Topics: []TopicConfig{
   104  			{
   105  				Topic:             topic1,
   106  				NumPartitions:     -1,
   107  				ReplicationFactor: -1,
   108  				ReplicaAssignments: []ReplicaAssignment{
   109  					{
   110  						Partition: 0,
   111  						Replicas:  []int{1},
   112  					},
   113  					{
   114  						Partition: 1,
   115  						Replicas:  []int{1},
   116  					},
   117  					{
   118  						Partition: 2,
   119  						Replicas:  []int{1},
   120  					},
   121  				},
   122  				ConfigEntries: config,
   123  			},
   124  			{
   125  				Topic:             topic2,
   126  				NumPartitions:     2,
   127  				ReplicationFactor: 1,
   128  				ConfigEntries:     config,
   129  			},
   130  			{
   131  				Topic:             topic3,
   132  				NumPartitions:     1,
   133  				ReplicationFactor: 1,
   134  				ConfigEntries:     config,
   135  			},
   136  		},
   137  	})
   138  	if err != nil {
   139  		t.Fatal(err)
   140  	}
   141  
   142  	defer deleteTopic(t, topic1, topic2, topic3)
   143  
   144  	expectTopics := map[string]struct{}{
   145  		topic1: {},
   146  		topic2: {},
   147  		topic3: {},
   148  	}
   149  
   150  	for topic, error := range res.Errors {
   151  		delete(expectTopics, topic)
   152  
   153  		if error != nil {
   154  			t.Errorf("%s => %s", topic, error)
   155  		}
   156  	}
   157  
   158  	for topic := range expectTopics {
   159  		t.Errorf("topic missing in response: %s", topic)
   160  	}
   161  }
   162  
   163  func TestCreateTopicsResponseV0(t *testing.T) {
   164  	item := createTopicsResponseV0{
   165  		TopicErrors: []createTopicsResponseV0TopicError{
   166  			{
   167  				Topic:     "topic",
   168  				ErrorCode: 2,
   169  			},
   170  		},
   171  	}
   172  
   173  	b := bytes.NewBuffer(nil)
   174  	w := &writeBuffer{w: b}
   175  	item.writeTo(w)
   176  
   177  	var found createTopicsResponseV0
   178  	remain, err := (&found).readFrom(bufio.NewReader(b), b.Len())
   179  	if err != nil {
   180  		t.Error(err)
   181  		t.FailNow()
   182  	}
   183  	if remain != 0 {
   184  		t.Errorf("expected 0 remain, got %v", remain)
   185  		t.FailNow()
   186  	}
   187  	if !reflect.DeepEqual(item, found) {
   188  		t.Error("expected item and found to be the same")
   189  		t.FailNow()
   190  	}
   191  }