Esempio n. 1
0
func TestHopByHopHeadersStrip(t *testing.T) {
	assert := assert.On(t)

	rawRequest := `GET /pkg/net/http/ HTTP/1.1
Host: golang.org
Connection: keep-alive,Foo, Bar
Foo: foo
Bar: bar
Proxy-Connection: keep-alive
Proxy-Authenticate: abc
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X; de-de) AppleWebKit/523.10.3 (KHTML, like Gecko) Version/3.0.4 Safari/523.10
Accept-Encoding: gzip
Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7
Cache-Control: no-cache
Accept-Language: de,en;q=0.7,en-us;q=0.3

`
	b := bufio.NewReader(strings.NewReader(rawRequest))
	req, err := http.ReadRequest(b)
	assert.Error(err).IsNil()
	assert.String(req.Header.Get("Foo")).Equals("foo")
	assert.String(req.Header.Get("Bar")).Equals("bar")
	assert.String(req.Header.Get("Connection")).Equals("keep-alive,Foo, Bar")
	assert.String(req.Header.Get("Proxy-Connection")).Equals("keep-alive")
	assert.String(req.Header.Get("Proxy-Authenticate")).Equals("abc")

	StripHopByHopHeaders(req)
	assert.String(req.Header.Get("Connection")).Equals("close")
	assert.String(req.Header.Get("Foo")).Equals("")
	assert.String(req.Header.Get("Bar")).Equals("")
	assert.String(req.Header.Get("Proxy-Connection")).Equals("")
	assert.String(req.Header.Get("Proxy-Authenticate")).Equals("")
}
Esempio n. 2
0
func TestHttpProxy(t *testing.T) {
	assert := assert.On(t)

	httpServer := &v2http.Server{
		Port:        net.Port(50042),
		PathHandler: make(map[string]http.HandlerFunc),
	}
	_, err := httpServer.Start()
	assert.Error(err).IsNil()
	defer httpServer.Close()

	assert.Error(InitializeServerSetOnce("test_5")).IsNil()

	transport := &http.Transport{
		Proxy: func(req *http.Request) (*url.URL, error) {
			return url.Parse("http://127.0.0.1:50040/")
		},
	}

	client := &http.Client{
		Transport: transport,
	}

	resp, err := client.Get("http://127.0.0.1:50042/")
	assert.Error(err).IsNil()
	assert.Int(resp.StatusCode).Equals(200)

	content, err := ioutil.ReadAll(resp.Body)
	assert.Error(err).IsNil()
	assert.String(string(content)).Equals("Home")

	CloseAllServers()
}
Esempio n. 3
0
func TestSwitchAccount(t *testing.T) {
	assert := assert.On(t)

	sa := &protocol.CommandSwitchAccount{
		Port:     1234,
		ID:       uuid.New(),
		AlterIds: 1024,
		Level:    128,
		ValidMin: 16,
	}

	buffer := buf.New()
	err := MarshalCommand(sa, buffer)
	assert.Error(err).IsNil()

	cmd, err := UnmarshalCommand(1, buffer.BytesFrom(2))
	assert.Error(err).IsNil()

	sa2, ok := cmd.(*protocol.CommandSwitchAccount)
	assert.Bool(ok).IsTrue()
	assert.Pointer(sa.Host).IsNil()
	assert.Pointer(sa2.Host).IsNil()
	assert.Port(sa.Port).Equals(sa2.Port)
	assert.String(sa.ID.String()).Equals(sa2.ID.String())
	assert.Uint16(sa.AlterIds).Equals(sa2.AlterIds)
	assert.Byte(byte(sa.Level)).Equals(byte(sa2.Level))
	assert.Byte(sa.ValidMin).Equals(sa2.ValidMin)
}
Esempio n. 4
0
func TestAccessLog(t *testing.T) {
	assert := assert.On(t)

	entry := &AccessLog{
		From:   "test_from",
		To:     "test_to",
		Status: "Accepted",
		Reason: "test_reason",
	}

	entryStr := entry.String()
	assert.String(entryStr).Contains("test_from")
	assert.String(entryStr).Contains("test_to")
	assert.String(entryStr).Contains("test_reason")
	assert.String(entryStr).Contains("Accepted")
}
Esempio n. 5
0
func TestChinaSitesJson(t *testing.T) {
	assert := assert.On(t)

	rule := ParseRule([]byte(`{
    "type": "chinasites",
    "outboundTag": "y"
  }`))
	assert.String(rule.Tag).Equals("y")
	cond, err := rule.BuildCondition()
	assert.Error(err).IsNil()
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("v.qq.com"), 80),
	})).IsTrue()
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("www.163.com"), 80),
	})).IsTrue()
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("ngacn.cc"), 80),
	})).IsTrue()
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("12306.cn"), 80),
	})).IsTrue()

	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("v2ray.com"), 80),
	})).IsFalse()
}
Esempio n. 6
0
func TestBuildAndRun(t *testing.T) {
	assert := assert.On(t)

	gopath := os.Getenv("GOPATH")
	goOS := parseOS(runtime.GOOS)
	goArch := parseArch(runtime.GOARCH)
	target := filepath.Join(gopath, "src", "v2ray_test")
	if goOS == Windows {
		target += ".exe"
	}
	err := buildV2Ray(target, "v1.0", goOS, goArch)
	assert.Error(err).IsNil()

	outBuffer := bytes.NewBuffer(make([]byte, 0, 1024))
	errBuffer := bytes.NewBuffer(make([]byte, 0, 1024))
	configFile := filepath.Join(gopath, "src", "github.com", "v2ray", "v2ray-core", "tools", "release", "config", "vpoint_socks_vmess.json")
	cmd := exec.Command(target, "--config="+configFile)
	cmd.Stdout = outBuffer
	cmd.Stderr = errBuffer
	cmd.Start()

	<-time.After(1 * time.Second)
	cmd.Process.Kill()

	outStr := string(outBuffer.Bytes())
	errStr := string(errBuffer.Bytes())

	assert.Bool(strings.Contains(outStr, "v1.0")).IsTrue()
	assert.String(errStr).Equals("")

	os.Remove(target)
}
Esempio n. 7
0
func TestChinaIPJson(t *testing.T) {
	assert := assert.On(t)

	rule := ParseRule([]byte(`{
    "type": "chinaip",
    "outboundTag": "x"
  }`))
	assert.String(rule.Tag).Equals("x")
	cond, err := rule.BuildCondition()
	assert.Error(err).IsNil()
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("121.14.1.189"), 80),
	})).IsTrue() // sina.com.cn
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("101.226.103.106"), 80),
	})).IsTrue() // qq.com
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("115.239.210.36"), 80),
	})).IsTrue() // image.baidu.com
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("120.135.126.1"), 80),
	})).IsTrue()

	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("8.8.8.8"), 80),
	})).IsFalse()
}
Esempio n. 8
0
func TestSimpleRouter(t *testing.T) {
	assert := assert.On(t)

	config := &Config{
		Rule: []*RoutingRule{
			{
				Tag: "test",
				NetworkList: &net.NetworkList{
					Network: []net.Network{net.Network_TCP},
				},
			},
		},
	}

	space := app.NewSpace()
	ctx := app.ContextWithSpace(context.Background(), space)
	assert.Error(app.AddApplicationToSpace(ctx, new(dns.Config))).IsNil()
	assert.Error(app.AddApplicationToSpace(ctx, new(dispatcher.Config))).IsNil()
	assert.Error(app.AddApplicationToSpace(ctx, new(proxyman.OutboundConfig))).IsNil()
	assert.Error(app.AddApplicationToSpace(ctx, config)).IsNil()
	assert.Error(space.Initialize()).IsNil()

	r := FromSpace(space)

	ctx = proxy.ContextWithDestination(ctx, net.TCPDestination(net.DomainAddress("v2ray.com"), 80))
	tag, err := r.TakeDetour(ctx)
	assert.Error(err).IsNil()
	assert.String(tag).Equals("test")
}
Esempio n. 9
0
func TestSimpleRouter(t *testing.T) {
	assert := assert.On(t)

	config := &Config{
		Rule: []*RoutingRule{
			{
				Tag: "test",
				NetworkList: &v2net.NetworkList{
					Network: []v2net.Network{v2net.Network_TCP},
				},
			},
		},
	}

	space := app.NewSpace()
	space.BindApp(dns.APP_ID, dns.NewCacheServer(space, &dns.Config{}))
	space.BindApp(dispatcher.APP_ID, dispatchers.NewDefaultDispatcher(space))
	space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, proxyman.NewDefaultOutboundHandlerManager())
	r := NewRouter(config, space)
	space.BindApp(APP_ID, r)
	assert.Error(space.Initialize()).IsNil()

	tag, err := r.TakeDetour(&proxy.SessionInfo{Destination: v2net.TCPDestination(v2net.DomainAddress("v2ray.com"), 80)})
	assert.Error(err).IsNil()
	assert.String(tag).Equals("test")
}
Esempio n. 10
0
func TestSocksInboundConfig(t *testing.T) {
	assert := assert.On(t)

	rawJson := `{
    "auth": "password",
    "accounts": [
      {
        "user": "******",
        "pass": "******"
      }
    ],
    "udp": false,
    "ip": "127.0.0.1",
    "timeout": 5
  }`

	config := new(SocksServerConfig)
	err := json.Unmarshal([]byte(rawJson), &config)
	assert.Error(err).IsNil()

	message, err := config.Build()
	assert.Error(err).IsNil()

	iConfig, err := message.GetInstance()
	assert.Error(err).IsNil()

	socksConfig := iConfig.(*socks.ServerConfig)
	assert.Bool(socksConfig.AuthType == socks.AuthType_PASSWORD).IsTrue()
	assert.Int(len(socksConfig.Accounts)).Equals(1)
	assert.String(socksConfig.Accounts["my-username"]).Equals("my-password")
	assert.Bool(socksConfig.UdpEnabled).IsFalse()
	assert.Address(socksConfig.Address.AsAddress()).Equals(net.LocalHostIP)
	assert.Uint32(socksConfig.Timeout).Equals(5)
}
Esempio n. 11
0
func TestBufferString(t *testing.T) {
	assert := assert.On(t)

	buffer := NewBuffer().Clear()
	defer buffer.Release()

	buffer.AppendString("Test String")
	assert.String(buffer.String()).Equals("Test String")
}
Esempio n. 12
0
func TestRandom(t *testing.T) {
	assert := assert.On(t)

	uuid := New()
	uuid2 := New()

	assert.String(uuid.String()).NotEquals(uuid2.String())
	assert.Bytes(uuid.Bytes()).NotEquals(uuid2.Bytes())
}
Esempio n. 13
0
func TestDomainParsing(t *testing.T) {
	assert := assert.On(t)

	rawJson := "\"v2ray.com\""
	var address Address
	err := json.Unmarshal([]byte(rawJson), &address)
	assert.Error(err).IsNil()
	assert.String(address.Domain()).Equals("v2ray.com")
}
Esempio n. 14
0
func TestBufferString(t *testing.T) {
	assert := assert.On(t)

	buffer := New()
	defer buffer.Release()

	buffer.AppendSupplier(serial.WriteString("Test String"))
	assert.String(buffer.String()).Equals("Test String")
}
Esempio n. 15
0
func TestUDPReaderWriter(t *testing.T) {
	assert := assert.On(t)

	user := &protocol.User{
		Account: serial.ToTypedMessage(&Account{
			Password:   "******",
			CipherType: CipherType_CHACHA20_IEFT,
		}),
	}
	cache := buf.New()
	writer := &UDPWriter{
		Writer: cache,
		Request: &protocol.RequestHeader{
			Version: Version,
			Address: v2net.DomainAddress("v2ray.com"),
			Port:    123,
			User:    user,
			Option:  RequestOptionOneTimeAuth,
		},
	}

	reader := &UDPReader{
		Reader: cache,
		User:   user,
	}

	b := buf.New()
	b.AppendSupplier(serial.WriteString("test payload"))
	err := writer.Write(b)
	assert.Error(err).IsNil()

	payload, err := reader.Read()
	assert.Error(err).IsNil()
	assert.String(payload.String()).Equals("test payload")

	b = buf.New()
	b.AppendSupplier(serial.WriteString("test payload 2"))
	err = writer.Write(b)
	assert.Error(err).IsNil()

	payload, err = reader.Read()
	assert.Error(err).IsNil()
	assert.String(payload.String()).Equals("test payload 2")
}
Esempio n. 16
0
func TestPassiveTCPConnection(t *testing.T) {
	assert := assert.On(t)

	tcpServer := &tcp.Server{
		MsgProcessor: func(data []byte) []byte {
			buffer := make([]byte, 0, 2048)
			buffer = append(buffer, []byte("Processed: ")...)
			buffer = append(buffer, data...)
			return buffer
		},
		SendFirst: []byte("Server sends first."),
	}
	_, err := tcpServer.Start()
	assert.Error(err).IsNil()
	defer tcpServer.Close()

	assert.Error(InitializeServerSetOnce("test_1")).IsNil()

	socksPort := v2net.Port(50002)

	conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{
		IP:   []byte{127, 0, 0, 1},
		Port: int(socksPort),
	})
	assert.Error(err).IsNil()

	authRequest := socks5AuthMethodRequest(byte(0))
	nBytes, err := conn.Write(authRequest)
	assert.Int(nBytes).Equals(len(authRequest))
	assert.Error(err).IsNil()

	authResponse := make([]byte, 1024)
	nBytes, err = conn.Read(authResponse)
	assert.Error(err).IsNil()
	assert.Bytes(authResponse[:nBytes]).Equals([]byte{socks5Version, 0})

	connectRequest := socks5Request(byte(1), v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), tcpServer.Port))
	nBytes, err = conn.Write(connectRequest)
	assert.Int(nBytes).Equals(len(connectRequest))
	assert.Error(err).IsNil()

	connectResponse := make([]byte, 1024)
	nBytes, err = conn.Read(connectResponse)
	assert.Error(err).IsNil()
	assert.Bytes(connectResponse[:nBytes]).Equals([]byte{socks5Version, 0, 0, 1, 0, 0, 0, 0, 6, 181})

	actualResponse := make([]byte, 1024)
	nResponse, err := conn.Read(actualResponse)
	assert.Error(err).IsNil()

	assert.String(string(actualResponse[:nResponse])).Equals(string(tcpServer.SendFirst))

	conn.Close()

	CloseAllServers()
}
Esempio n. 17
0
func TestNewUUID(t *testing.T) {
	assert := assert.On(t)

	uuid := New()
	uuid2, err := ParseString(uuid.String())

	assert.Error(err).IsNil()
	assert.String(uuid.String()).Equals(uuid2.String())
	assert.Bytes(uuid.Bytes()).Equals(uuid2.Bytes())
}
Esempio n. 18
0
func TestServerSampleConfig(t *testing.T) {
	assert := assert.On(t)

	GOPATH := os.Getenv("GOPATH")
	baseDir := filepath.Join(GOPATH, "src", "v2ray.com", "core", "tools", "release", "config")

	pointConfig, err := LoadConfig(filepath.Join(baseDir, "vpoint_vmess_freedom.json"))
	assert.Error(err).IsNil()

	assert.Pointer(pointConfig.InboundConfig).IsNotNil()
	assert.Port(pointConfig.InboundConfig.Port).IsValid()
	assert.Pointer(pointConfig.OutboundConfig).IsNotNil()

	assert.String(pointConfig.InboundConfig.Protocol).Equals("vmess")
	assert.Pointer(pointConfig.InboundConfig.Settings).IsNotNil()

	assert.String(pointConfig.OutboundConfig.Protocol).Equals("freedom")
	assert.Pointer(pointConfig.OutboundConfig.Settings).IsNotNil()
}
Esempio n. 19
0
func TestConnectionCache(t *testing.T) {
	assert := assert.On(t)

	pool := NewConnectionPool()
	conn := pool.Get(NewConnectionID(v2net.LocalHostIP, v2net.TCPDestination(v2net.LocalHostIP, v2net.Port(80))))
	assert.Pointer(conn).IsNil()

	pool.Put(NewConnectionID(v2net.LocalHostIP, v2net.TCPDestination(v2net.LocalHostIP, v2net.Port(80))), &TestConnection{id: "test"})
	conn = pool.Get(NewConnectionID(v2net.LocalHostIP, v2net.TCPDestination(v2net.LocalHostIP, v2net.Port(80))))
	assert.String(conn.(*TestConnection).id).Equals("test")
}
Esempio n. 20
0
func TestDomainParsing(t *testing.T) {
	assert := assert.On(t)

	rawJson := "\"v2ray.com\""
	var address AddressJson
	err := json.Unmarshal([]byte(rawJson), &address)
	assert.Error(err).IsNil()
	assert.Bool(address.Address.Family().Either(AddressFamilyIPv4)).IsFalse()
	assert.Bool(address.Address.Family().Either(AddressFamilyDomain)).IsTrue()
	assert.String(address.Address.Domain()).Equals("v2ray.com")
}
Esempio n. 21
0
func TestDomainAddress(t *testing.T) {
	assert := assert.On(t)

	domain := "v2ray.com"
	addr := v2net.DomainAddress(domain)

	assert.Address(addr).IsDomain()
	assert.Address(addr).IsNotIPv6()
	assert.Address(addr).IsNotIPv4()
	assert.String(addr.Domain()).Equals(domain)
	assert.Address(addr).EqualsString("v2ray.com")
}
Esempio n. 22
0
func TestBufferWrite(t *testing.T) {
	assert := assert.On(t)

	buffer := NewLocal(8)
	nBytes, err := buffer.Write([]byte("abcd"))
	assert.Error(err).IsNil()
	assert.Int(nBytes).Equals(4)
	nBytes, err = buffer.Write([]byte("abcde"))
	assert.Error(err).IsNil()
	assert.Int(nBytes).Equals(4)
	assert.String(buffer.String()).Equals("abcdabcd")
}
Esempio n. 23
0
func TestUDPReaderWriter(t *testing.T) {
	assert := assert.On(t)

	user := &protocol.User{
		Account: loader.NewTypedSettings(&Account{
			Password:   "******",
			CipherType: CipherType_CHACHA20_IEFT,
		}),
	}
	cache := alloc.NewBuffer().Clear()
	writer := &UDPWriter{
		Writer: cache,
		Request: &protocol.RequestHeader{
			Version: Version,
			Address: v2net.DomainAddress("v2ray.com"),
			Port:    123,
			User:    user,
			Option:  RequestOptionOneTimeAuth,
		},
	}

	reader := &UDPReader{
		Reader: cache,
		User:   user,
	}

	err := writer.Write(alloc.NewBuffer().Clear().AppendString("test payload"))
	assert.Error(err).IsNil()

	payload, err := reader.Read()
	assert.Error(err).IsNil()
	assert.String(payload.String()).Equals("test payload")

	err = writer.Write(alloc.NewBuffer().Clear().AppendString("test payload 2"))
	assert.Error(err).IsNil()

	payload, err = reader.Read()
	assert.Error(err).IsNil()
	assert.String(payload.String()).Equals("test payload 2")
}
Esempio n. 24
0
func TestDialWithLocalAddr(t *testing.T) {
	assert := assert.On(t)

	server := &tcp.Server{}
	dest, err := server.Start()
	assert.Error(err).IsNil()
	defer server.Close()

	conn, err := DialToDest(v2net.LocalHostIP, v2net.TCPDestination(v2net.LocalHostIP, dest.Port))
	assert.Error(err).IsNil()
	assert.String(conn.RemoteAddr().String()).Equals("127.0.0.1:" + dest.Port.String())
	conn.Close()
}
Esempio n. 25
0
func TestDialDomain(t *testing.T) {
	assert := assert.On(t)

	server := &tcp.Server{}
	dest, err := server.Start()
	assert.Error(err).IsNil()
	defer server.Close()

	conn, err := DialToDest(nil, v2net.TCPDestination(v2net.DomainAddress("local.v2ray.com"), dest.Port))
	assert.Error(err).IsNil()
	assert.String(conn.RemoteAddr().String()).Equals("127.0.0.1:" + dest.Port.String())
	conn.Close()
}
Esempio n. 26
0
func TestParseBytes(t *testing.T) {
	assert := assert.On(t)

	str := "2418d087-648d-4990-86e8-19dca1d006d3"
	bytes := []byte{0x24, 0x18, 0xd0, 0x87, 0x64, 0x8d, 0x49, 0x90, 0x86, 0xe8, 0x19, 0xdc, 0xa1, 0xd0, 0x06, 0xd3}

	uuid, err := ParseBytes(bytes)
	assert.Error(err).IsNil()
	assert.String(uuid.String()).Equals(str)

	_, err = ParseBytes([]byte{1, 3, 2, 4})
	assert.Error(err).Equals(ErrInvalidID)
}
Esempio n. 27
0
func TestSocksOutboundConfig(t *testing.T) {
	assert := assert.On(t)

	rawJson := `{
    "servers": [{
      "address": "127.0.0.1",
      "port": 1234,
      "users": [
        {"user": "******", "pass": "******", "email": "*****@*****.**"}
      ]
    }]
  }`

	config := new(SocksClientConfig)
	err := json.Unmarshal([]byte(rawJson), &config)
	assert.Error(err).IsNil()

	message, err := config.Build()
	assert.Error(err).IsNil()

	iConfig, err := message.GetInstance()
	assert.Error(err).IsNil()

	socksConfig := iConfig.(*socks.ClientConfig)
	assert.Int(len(socksConfig.Server)).Equals(1)

	ss := protocol.NewServerSpecFromPB(*socksConfig.Server[0])
	assert.Destination(ss.Destination()).EqualsString("tcp:127.0.0.1:1234")

	user := ss.PickUser()
	assert.String(user.Email).Equals("*****@*****.**")

	account, err := user.GetTypedAccount()
	assert.Error(err).IsNil()

	socksAccount := account.(*socks.Account)
	assert.String(socksAccount.Username).Equals("test user")
	assert.String(socksAccount.Password).Equals("test pass")
}
Esempio n. 28
0
func TestUserParsing(t *testing.T) {
	assert := assert.On(t)

	user := new(User)
	err := json.Unmarshal([]byte(`{
    "id": "96edb838-6d68-42ef-a933-25f7ac3a9d09",
    "email": "*****@*****.**",
    "level": 1,
    "alterId": 100
  }`), user)
	assert.Error(err).IsNil()
	assert.Byte(byte(user.Level)).Equals(1)
	assert.String(user.Email).Equals("*****@*****.**")
}
Esempio n. 29
0
func TestChinaIPJson(t *testing.T) {
	assert := assert.On(t)

	rule := ParseRule([]byte(`{
    "type": "chinaip",
    "outboundTag": "x"
  }`))
	assert.String(rule.Tag).Equals("x")
	assert.Bool(rule.Apply(makeDestination("121.14.1.189"))).IsTrue()    // sina.com.cn
	assert.Bool(rule.Apply(makeDestination("101.226.103.106"))).IsTrue() // qq.com
	assert.Bool(rule.Apply(makeDestination("115.239.210.36"))).IsTrue()  // image.baidu.com
	assert.Bool(rule.Apply(makeDestination("120.135.126.1"))).IsTrue()

	assert.Bool(rule.Apply(makeDestination("8.8.8.8"))).IsFalse()
}
Esempio n. 30
0
func TestErrorOrFinish2_Error2(t *testing.T) {
	assert := assert.On(t)

	c1 := make(chan error, 1)
	c2 := make(chan error, 2)
	c := make(chan error, 1)

	go func() {
		c <- ErrorOrFinish2(c1, c2)
	}()

	c2 <- errors.New("test")
	err := <-c
	assert.String(err.Error()).Equals("test")
}