blob: 69c14c74545baa0661fb4d9f0812d200fc08a8f1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 golang
import (
"context"
"fmt"
"testing"
"time"
"github.com/apache/rocketmq-clients/golang/v5/credentials"
v2 "github.com/apache/rocketmq-clients/golang/v5/protocol/v2"
gomock "github.com/golang/mock/gomock"
"github.com/prashantv/gostub"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
"go.uber.org/zap/zaptest/observer"
)
func BuildCLient(t *testing.T) *defaultClient {
stubs := gostub.Stub(&defaultClientManagerOptions, clientManagerOptions{
RPC_CLIENT_MAX_IDLE_DURATION: time.Second,
RPC_CLIENT_IDLE_CHECK_INITIAL_DELAY: time.Hour,
RPC_CLIENT_IDLE_CHECK_PERIOD: time.Hour,
HEART_BEAT_INITIAL_DELAY: time.Hour,
HEART_BEAT_PERIOD: time.Hour,
LOG_STATS_INITIAL_DELAY: time.Hour,
LOG_STATS_PERIOD: time.Hour,
SYNC_SETTINGS_DELAY: time.Hour,
SYNC_SETTINGS_PERIOD: time.Hour,
})
stubs2 := gostub.Stub(&NewRpcClient, func(target string, opts ...RpcClientOption) (RpcClient, error) {
if target == fakeAddress {
return MOCK_RPC_CLIENT, nil
}
return nil, fmt.Errorf("invalid target=%s", target)
})
defer func() {
stubs.Reset()
stubs2.Reset()
}()
MOCK_RPC_CLIENT.EXPECT().Telemetry(gomock.Any()).Return(&MOCK_MessagingService_TelemetryClient{
trace: make([]string, 0),
}, nil)
endpoints := fmt.Sprintf("%s:%d", fakeHost, fakePort)
cli, err := NewClientConcrete(&Config{
Endpoint: endpoints,
Credentials: &credentials.SessionCredentials{},
})
if err != nil {
t.Error(err)
}
sugarBaseLogger.Info(cli)
err = cli.startUp()
if err != nil {
t.Error(err)
}
return cli
}
func GetClientAndDefaultClientSession(t *testing.T) (*defaultClient, *defaultClientSession) {
cli := BuildCLient(t)
default_cli_session, err := cli.getDefaultClientSession(fakeAddress)
if err != nil {
t.Error(err)
}
return cli, default_cli_session
}
func PrepareTestLogger(cli *defaultClient) *observer.ObservedLogs {
observedZapCore, observedLogs := observer.New(zap.InfoLevel)
observedLogger := zap.New(observedZapCore)
cli.log = observedLogger.Sugar()
return observedLogs
}
func TestCLINewClient(t *testing.T) {
stubs := gostub.Stub(&defaultClientManagerOptions, clientManagerOptions{
RPC_CLIENT_MAX_IDLE_DURATION: time.Second,
RPC_CLIENT_IDLE_CHECK_INITIAL_DELAY: time.Hour,
RPC_CLIENT_IDLE_CHECK_PERIOD: time.Hour,
HEART_BEAT_INITIAL_DELAY: time.Hour,
HEART_BEAT_PERIOD: time.Hour,
LOG_STATS_INITIAL_DELAY: time.Hour,
LOG_STATS_PERIOD: time.Hour,
SYNC_SETTINGS_DELAY: time.Hour,
SYNC_SETTINGS_PERIOD: time.Hour,
})
stubs2 := gostub.Stub(&NewRpcClient, func(target string, opts ...RpcClientOption) (RpcClient, error) {
if target == fakeAddress {
return MOCK_RPC_CLIENT, nil
}
return nil, fmt.Errorf("invalid target=%s", target)
})
defer func() {
stubs.Reset()
stubs2.Reset()
}()
MOCK_RPC_CLIENT.EXPECT().Telemetry(gomock.Any()).Return(&MOCK_MessagingService_TelemetryClient{
trace: make([]string, 0),
}, nil)
endpoints := fmt.Sprintf("%s:%d", fakeHost, fakePort)
cli, err := NewClient(&Config{
Endpoint: endpoints,
Credentials: &credentials.SessionCredentials{},
})
if err != nil {
t.Error(err)
}
sugarBaseLogger.Info(cli)
err = cli.(*defaultClient).startUp()
if err != nil {
t.Error(err)
}
}
func Test_acquire_observer_uninitialized(t *testing.T) {
// given
_, default_cli_session := GetClientAndDefaultClientSession(t)
// when
observer, acquired_observer := default_cli_session._acquire_observer()
// then
if acquired_observer {
t.Error("Acquired observer even though it is uninitialized")
}
if observer != nil {
t.Error("Observer should be nil")
}
}
func Test_acquire_observer_initialized(t *testing.T) {
// given
_, default_cli_session := GetClientAndDefaultClientSession(t)
default_cli_session.publish(context.TODO(), &v2.TelemetryCommand{})
// when
observer, acquired_observer := default_cli_session._acquire_observer()
// then
if !acquired_observer {
t.Error("Failed to acquire observer even though it is uninitialized")
}
if observer == nil {
t.Error("Observer should be not nil")
}
}
func Test_execute_server_telemetry_command_fail(t *testing.T) {
// given
cli, default_cli_session := GetClientAndDefaultClientSession(t)
default_cli_session.publish(context.TODO(), &v2.TelemetryCommand{})
observedLogs := PrepareTestLogger(cli)
// when
default_cli_session._execute_server_telemetry_command(&v2.TelemetryCommand{})
// then
require.Equal(t, 1, observedLogs.Len())
commandExecutionLog := observedLogs.All()[0]
assert.Equal(t, "telemetryCommand recv err=%!w(*errors.errorString=&{handleTelemetryCommand err = Command is nil})", commandExecutionLog.Message)
}
func Test_execute_server_telemetry_command(t *testing.T) {
// given
cli, default_cli_session := GetClientAndDefaultClientSession(t)
default_cli_session.publish(context.TODO(), &v2.TelemetryCommand{})
observedLogs := PrepareTestLogger(cli)
// when
default_cli_session._execute_server_telemetry_command(&v2.TelemetryCommand{Command: &v2.TelemetryCommand_RecoverOrphanedTransactionCommand{}})
// then
require.Equal(t, 2, observedLogs.Len())
commandExecutionLog := observedLogs.All()[1]
assert.Equal(t, "Executed command successfully", commandExecutionLog.Message)
}
func TestRestoreDefaultClientSessionZeroErrors(t *testing.T) {
// given
cli := BuildCLient(t)
default_cli_session, err := cli.getDefaultClientSession(fakeAddress)
if err != nil {
t.Error(err)
}
default_cli_session.publish(context.TODO(), &v2.TelemetryCommand{})
observedLogs := PrepareTestLogger(cli)
default_cli_session.observer = &MOCK_MessagingService_TelemetryClient{
recv_error_count: 0,
cli: cli,
}
default_cli_session.recoveryWaitTime = time.Second
cli.settings = &simpleConsumerSettings{}
// when
// we wait some time while consumer goroutine runs
time.Sleep(3 * time.Second)
// then
commandExecutionLog := observedLogs.All()[:2]
assert.Equal(t, "Executed command successfully", commandExecutionLog[0].Message)
assert.Equal(t, "Executed command successfully", commandExecutionLog[1].Message)
}
func TestRestoreDefaultClientSessionOneError(t *testing.T) {
// given
cli := BuildCLient(t)
default_cli_session, err := cli.getDefaultClientSession(fakeAddress)
if err != nil {
t.Error(err)
}
default_cli_session.publish(context.TODO(), &v2.TelemetryCommand{})
observedLogs := PrepareTestLogger(cli)
default_cli_session.observer = &MOCK_MessagingService_TelemetryClient{
recv_error_count: 1,
cli: cli,
}
default_cli_session.recoveryWaitTime = time.Second
cli.settings = &simpleConsumerSettings{}
// when
// we wait some time while consumer goroutine runs
time.Sleep(3 * time.Second)
// then
commandExecutionLog := observedLogs.All()[:3]
assert.Equal(t, "Encountered error while receiving TelemetryCommand, trying to recover", commandExecutionLog[0].Message)
assert.Equal(t, "Managed to recover, executing message", commandExecutionLog[1].Message)
assert.Equal(t, "Executed command successfully", commandExecutionLog[2].Message)
}
func TestRestoreDefaultClientSessionTwoErrors(t *testing.T) {
// given
cli := BuildCLient(t)
default_cli_session, err := cli.getDefaultClientSession(fakeAddress)
if err != nil {
t.Error(err)
}
default_cli_session.publish(context.TODO(), &v2.TelemetryCommand{})
observedLogs := PrepareTestLogger(cli)
default_cli_session.observer = &MOCK_MessagingService_TelemetryClient{
recv_error_count: 2,
cli: cli,
}
default_cli_session.recoveryWaitTime = time.Second
cli.settings = &simpleConsumerSettings{}
// when
// we wait some time while consumer goroutine runs
time.Sleep(3 * time.Second)
// then
commandExecutionLog := observedLogs.All()[:2]
assert.Equal(t, "Encountered error while receiving TelemetryCommand, trying to recover", commandExecutionLog[0].Message)
assert.Equal(t, "Failed to recover, err=%wEOF", commandExecutionLog[1].Message)
}