// +build !appengine

/*
 *
 * Copyright 2018 gRPC authors.
 *
 * 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 internal_test

import (
	"net"
	"syscall"
	"testing"

	"google.golang.org/grpc/credentials/internal"
)

type syscallConn struct {
	net.Conn
}

func (*syscallConn) SyscallConn() (syscall.RawConn, error) {
	return nil, nil
}

type nonSyscallConn struct {
	net.Conn
}

func TestWrapSyscallConn(t *testing.T) {
	sc := &syscallConn{}
	nsc := &nonSyscallConn{}

	wrapConn := internal.WrapSyscallConn(sc, nsc)
	if _, ok := wrapConn.(syscall.Conn); !ok {
		t.Errorf("returned conn (type %T) doesn't implement syscall.Conn, want implement", wrapConn)
	}
}

func TestWrapSyscallConnNoWrap(t *testing.T) {
	nscRaw := &nonSyscallConn{}
	nsc := &nonSyscallConn{}

	wrapConn := internal.WrapSyscallConn(nscRaw, nsc)
	if _, ok := wrapConn.(syscall.Conn); ok {
		t.Errorf("returned conn (type %T) implements syscall.Conn, want not implement", wrapConn)
	}
	if wrapConn != nsc {
		t.Errorf("returned conn is %p, want %p (the passed-in newConn)", wrapConn, nsc)
	}
}
