Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
42f20102
Commit
42f20102
authored
Jan 27, 2017
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
libgo: update to go1.8rc3
Reviewed-on:
https://go-review.googlesource.com/35844
From-SVN: r244981
parent
3f54004b
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
389 additions
and
92 deletions
+389
-92
libgo/MERGE
+1
-1
libgo/VERSION
+1
-1
libgo/go/cmd/go/go_test.go
+23
-0
libgo/go/cmd/go/pkg.go
+1
-1
libgo/go/database/sql/sql.go
+64
-27
libgo/go/database/sql/sql_test.go
+99
-24
libgo/go/go/printer/nodes.go
+12
-5
libgo/go/go/printer/printer.go
+8
-3
libgo/go/go/printer/testdata/comments2.golden
+59
-0
libgo/go/go/printer/testdata/comments2.input
+63
-0
libgo/go/net/http/client.go
+13
-8
libgo/go/net/http/client_test.go
+41
-20
libgo/go/net/http/serve_test.go
+1
-1
libgo/merge.sh
+3
-1
No files found.
libgo/MERGE
View file @
42f20102
59f181b6fda68ece22882945853ca2df9dbf1c88
2a5f65a98ca483aad2dd74dc2636a7baecc59cf2
The first line of this file holds the git revision number of the
The first line of this file holds the git revision number of the
last merge done from the master library sources.
last merge done from the master library sources.
libgo/VERSION
View file @
42f20102
go1.8rc
2
go1.8rc
3
libgo/go/cmd/go/go_test.go
View file @
42f20102
...
@@ -3787,3 +3787,26 @@ GLOBL ·constants<>(SB),8,$8
...
@@ -3787,3 +3787,26 @@ GLOBL ·constants<>(SB),8,$8
tg
.
setenv
(
"GOPATH"
,
tg
.
path
(
"go"
))
tg
.
setenv
(
"GOPATH"
,
tg
.
path
(
"go"
))
tg
.
run
(
"build"
,
"p"
)
tg
.
run
(
"build"
,
"p"
)
}
}
// Issue 18778.
func
TestDotDotDotOutsideGOPATH
(
t
*
testing
.
T
)
{
tg
:=
testgo
(
t
)
defer
tg
.
cleanup
()
tg
.
tempFile
(
"pkgs/a.go"
,
`package x`
)
tg
.
tempFile
(
"pkgs/a_test.go"
,
`package x_test
import "testing"
func TestX(t *testing.T) {}`
)
tg
.
tempFile
(
"pkgs/a/a.go"
,
`package a`
)
tg
.
tempFile
(
"pkgs/a/a_test.go"
,
`package a_test
import "testing"
func TestA(t *testing.T) {}`
)
tg
.
cd
(
tg
.
path
(
"pkgs"
))
tg
.
run
(
"build"
,
"./..."
)
tg
.
run
(
"test"
,
"./..."
)
tg
.
run
(
"list"
,
"./..."
)
tg
.
grepStdout
(
"pkgs$"
,
"expected package not listed"
)
tg
.
grepStdout
(
"pkgs/a"
,
"expected package not listed"
)
}
libgo/go/cmd/go/pkg.go
View file @
42f20102
...
@@ -433,7 +433,7 @@ func setErrorPos(p *Package, importPos []token.Position) *Package {
...
@@ -433,7 +433,7 @@ func setErrorPos(p *Package, importPos []token.Position) *Package {
func
cleanImport
(
path
string
)
string
{
func
cleanImport
(
path
string
)
string
{
orig
:=
path
orig
:=
path
path
=
pathpkg
.
Clean
(
path
)
path
=
pathpkg
.
Clean
(
path
)
if
strings
.
HasPrefix
(
orig
,
"./"
)
&&
path
!=
".."
&&
path
!=
"."
&&
!
strings
.
HasPrefix
(
path
,
"../"
)
{
if
strings
.
HasPrefix
(
orig
,
"./"
)
&&
path
!=
".."
&&
!
strings
.
HasPrefix
(
path
,
"../"
)
{
path
=
"./"
+
path
path
=
"./"
+
path
}
}
return
path
return
path
...
...
libgo/go/database/sql/sql.go
View file @
42f20102
...
@@ -1357,16 +1357,7 @@ func (db *DB) begin(ctx context.Context, opts *TxOptions, strategy connReuseStra
...
@@ -1357,16 +1357,7 @@ func (db *DB) begin(ctx context.Context, opts *TxOptions, strategy connReuseStra
cancel
:
cancel
,
cancel
:
cancel
,
ctx
:
ctx
,
ctx
:
ctx
,
}
}
go
func
(
tx
*
Tx
)
{
go
tx
.
awaitDone
()
select
{
case
<-
tx
.
ctx
.
Done
()
:
if
!
tx
.
isDone
()
{
// Discard and close the connection used to ensure the transaction
// is closed and the resources are released.
tx
.
rollback
(
true
)
}
}
}(
tx
)
return
tx
,
nil
return
tx
,
nil
}
}
...
@@ -1388,6 +1379,11 @@ func (db *DB) Driver() driver.Driver {
...
@@ -1388,6 +1379,11 @@ func (db *DB) Driver() driver.Driver {
type
Tx
struct
{
type
Tx
struct
{
db
*
DB
db
*
DB
// closemu prevents the transaction from closing while there
// is an active query. It is held for read during queries
// and exclusively during close.
closemu
sync
.
RWMutex
// dc is owned exclusively until Commit or Rollback, at which point
// dc is owned exclusively until Commit or Rollback, at which point
// it's returned with putConn.
// it's returned with putConn.
dc
*
driverConn
dc
*
driverConn
...
@@ -1413,6 +1409,20 @@ type Tx struct {
...
@@ -1413,6 +1409,20 @@ type Tx struct {
ctx
context
.
Context
ctx
context
.
Context
}
}
// awaitDone blocks until the context in Tx is canceled and rolls back
// the transaction if it's not already done.
func
(
tx
*
Tx
)
awaitDone
()
{
// Wait for either the transaction to be committed or rolled
// back, or for the associated context to be closed.
<-
tx
.
ctx
.
Done
()
// Discard and close the connection used to ensure the
// transaction is closed and the resources are released. This
// rollback does nothing if the transaction has already been
// committed or rolled back.
tx
.
rollback
(
true
)
}
func
(
tx
*
Tx
)
isDone
()
bool
{
func
(
tx
*
Tx
)
isDone
()
bool
{
return
atomic
.
LoadInt32
(
&
tx
.
done
)
!=
0
return
atomic
.
LoadInt32
(
&
tx
.
done
)
!=
0
}
}
...
@@ -1424,16 +1434,31 @@ var ErrTxDone = errors.New("sql: Transaction has already been committed or rolle
...
@@ -1424,16 +1434,31 @@ var ErrTxDone = errors.New("sql: Transaction has already been committed or rolle
// close returns the connection to the pool and
// close returns the connection to the pool and
// must only be called by Tx.rollback or Tx.Commit.
// must only be called by Tx.rollback or Tx.Commit.
func
(
tx
*
Tx
)
close
(
err
error
)
{
func
(
tx
*
Tx
)
close
(
err
error
)
{
tx
.
closemu
.
Lock
()
defer
tx
.
closemu
.
Unlock
()
tx
.
db
.
putConn
(
tx
.
dc
,
err
)
tx
.
db
.
putConn
(
tx
.
dc
,
err
)
tx
.
cancel
()
tx
.
cancel
()
tx
.
dc
=
nil
tx
.
dc
=
nil
tx
.
txi
=
nil
tx
.
txi
=
nil
}
}
// hookTxGrabConn specifies an optional hook to be called on
// a successful call to (*Tx).grabConn. For tests.
var
hookTxGrabConn
func
()
func
(
tx
*
Tx
)
grabConn
(
ctx
context
.
Context
)
(
*
driverConn
,
error
)
{
func
(
tx
*
Tx
)
grabConn
(
ctx
context
.
Context
)
(
*
driverConn
,
error
)
{
select
{
default
:
case
<-
ctx
.
Done
()
:
return
nil
,
ctx
.
Err
()
}
if
tx
.
isDone
()
{
if
tx
.
isDone
()
{
return
nil
,
ErrTxDone
return
nil
,
ErrTxDone
}
}
if
hookTxGrabConn
!=
nil
{
// test hook
hookTxGrabConn
()
}
return
tx
.
dc
,
nil
return
tx
.
dc
,
nil
}
}
...
@@ -1503,6 +1528,9 @@ func (tx *Tx) Rollback() error {
...
@@ -1503,6 +1528,9 @@ func (tx *Tx) Rollback() error {
// for the execution of the returned statement. The returned statement
// for the execution of the returned statement. The returned statement
// will run in the transaction context.
// will run in the transaction context.
func
(
tx
*
Tx
)
PrepareContext
(
ctx
context
.
Context
,
query
string
)
(
*
Stmt
,
error
)
{
func
(
tx
*
Tx
)
PrepareContext
(
ctx
context
.
Context
,
query
string
)
(
*
Stmt
,
error
)
{
tx
.
closemu
.
RLock
()
defer
tx
.
closemu
.
RUnlock
()
// TODO(bradfitz): We could be more efficient here and either
// TODO(bradfitz): We could be more efficient here and either
// provide a method to take an existing Stmt (created on
// provide a method to take an existing Stmt (created on
// perhaps a different Conn), and re-create it on this Conn if
// perhaps a different Conn), and re-create it on this Conn if
...
@@ -1567,6 +1595,9 @@ func (tx *Tx) Prepare(query string) (*Stmt, error) {
...
@@ -1567,6 +1595,9 @@ func (tx *Tx) Prepare(query string) (*Stmt, error) {
// The returned statement operates within the transaction and will be closed
// The returned statement operates within the transaction and will be closed
// when the transaction has been committed or rolled back.
// when the transaction has been committed or rolled back.
func
(
tx
*
Tx
)
StmtContext
(
ctx
context
.
Context
,
stmt
*
Stmt
)
*
Stmt
{
func
(
tx
*
Tx
)
StmtContext
(
ctx
context
.
Context
,
stmt
*
Stmt
)
*
Stmt
{
tx
.
closemu
.
RLock
()
defer
tx
.
closemu
.
RUnlock
()
// TODO(bradfitz): optimize this. Currently this re-prepares
// TODO(bradfitz): optimize this. Currently this re-prepares
// each time. This is fine for now to illustrate the API but
// each time. This is fine for now to illustrate the API but
// we should really cache already-prepared statements
// we should really cache already-prepared statements
...
@@ -1618,6 +1649,9 @@ func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
...
@@ -1618,6 +1649,9 @@ func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
// ExecContext executes a query that doesn't return rows.
// ExecContext executes a query that doesn't return rows.
// For example: an INSERT and UPDATE.
// For example: an INSERT and UPDATE.
func
(
tx
*
Tx
)
ExecContext
(
ctx
context
.
Context
,
query
string
,
args
...
interface
{})
(
Result
,
error
)
{
func
(
tx
*
Tx
)
ExecContext
(
ctx
context
.
Context
,
query
string
,
args
...
interface
{})
(
Result
,
error
)
{
tx
.
closemu
.
RLock
()
defer
tx
.
closemu
.
RUnlock
()
dc
,
err
:=
tx
.
grabConn
(
ctx
)
dc
,
err
:=
tx
.
grabConn
(
ctx
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
@@ -1661,6 +1695,9 @@ func (tx *Tx) Exec(query string, args ...interface{}) (Result, error) {
...
@@ -1661,6 +1695,9 @@ func (tx *Tx) Exec(query string, args ...interface{}) (Result, error) {
// QueryContext executes a query that returns rows, typically a SELECT.
// QueryContext executes a query that returns rows, typically a SELECT.
func
(
tx
*
Tx
)
QueryContext
(
ctx
context
.
Context
,
query
string
,
args
...
interface
{})
(
*
Rows
,
error
)
{
func
(
tx
*
Tx
)
QueryContext
(
ctx
context
.
Context
,
query
string
,
args
...
interface
{})
(
*
Rows
,
error
)
{
tx
.
closemu
.
RLock
()
defer
tx
.
closemu
.
RUnlock
()
dc
,
err
:=
tx
.
grabConn
(
ctx
)
dc
,
err
:=
tx
.
grabConn
(
ctx
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
@@ -2038,25 +2075,21 @@ type Rows struct {
...
@@ -2038,25 +2075,21 @@ type Rows struct {
// closed value is 1 when the Rows is closed.
// closed value is 1 when the Rows is closed.
// Use atomic operations on value when checking value.
// Use atomic operations on value when checking value.
closed
int32
closed
int32
c
txClose
chan
struct
{}
// closed when Rows is closed, may be nul
l.
c
ancel
func
()
// called when Rows is closed, may be ni
l.
lastcols
[]
driver
.
Value
lastcols
[]
driver
.
Value
lasterr
error
// non-nil only if closed is true
lasterr
error
// non-nil only if closed is true
closeStmt
*
driverStmt
// if non-nil, statement to Close on close
closeStmt
*
driverStmt
// if non-nil, statement to Close on close
}
}
func
(
rs
*
Rows
)
initContextClose
(
ctx
context
.
Context
)
{
func
(
rs
*
Rows
)
initContextClose
(
ctx
context
.
Context
)
{
if
ctx
.
Done
()
==
context
.
Background
()
.
Done
()
{
ctx
,
rs
.
cancel
=
context
.
WithCancel
(
ctx
)
return
go
rs
.
awaitDone
(
ctx
)
}
}
rs
.
ctxClose
=
make
(
chan
struct
{})
// awaitDone blocks until the rows are closed or the context canceled.
go
func
()
{
func
(
rs
*
Rows
)
awaitDone
(
ctx
context
.
Context
)
{
select
{
<-
ctx
.
Done
()
case
<-
ctx
.
Done
()
:
rs
.
Close
()
rs
.
Close
()
case
<-
rs
.
ctxClose
:
}
}()
}
}
// Next prepares the next result row for reading with the Scan method. It
// Next prepares the next result row for reading with the Scan method. It
...
@@ -2314,7 +2347,9 @@ func (rs *Rows) Scan(dest ...interface{}) error {
...
@@ -2314,7 +2347,9 @@ func (rs *Rows) Scan(dest ...interface{}) error {
return
nil
return
nil
}
}
var
rowsCloseHook
func
(
*
Rows
,
*
error
)
// rowsCloseHook returns a function so tests may install the
// hook throug a test only mutex.
var
rowsCloseHook
=
func
()
func
(
*
Rows
,
*
error
)
{
return
nil
}
func
(
rs
*
Rows
)
isClosed
()
bool
{
func
(
rs
*
Rows
)
isClosed
()
bool
{
return
atomic
.
LoadInt32
(
&
rs
.
closed
)
!=
0
return
atomic
.
LoadInt32
(
&
rs
.
closed
)
!=
0
...
@@ -2328,13 +2363,15 @@ func (rs *Rows) Close() error {
...
@@ -2328,13 +2363,15 @@ func (rs *Rows) Close() error {
if
!
atomic
.
CompareAndSwapInt32
(
&
rs
.
closed
,
0
,
1
)
{
if
!
atomic
.
CompareAndSwapInt32
(
&
rs
.
closed
,
0
,
1
)
{
return
nil
return
nil
}
}
if
rs
.
ctxClose
!=
nil
{
close
(
rs
.
ctxClose
)
}
err
:=
rs
.
rowsi
.
Close
()
err
:=
rs
.
rowsi
.
Close
()
if
fn
:=
rowsCloseHook
;
fn
!=
nil
{
if
fn
:=
rowsCloseHook
()
;
fn
!=
nil
{
fn
(
rs
,
&
err
)
fn
(
rs
,
&
err
)
}
}
if
rs
.
cancel
!=
nil
{
rs
.
cancel
()
}
if
rs
.
closeStmt
!=
nil
{
if
rs
.
closeStmt
!=
nil
{
rs
.
closeStmt
.
Close
()
rs
.
closeStmt
.
Close
()
}
}
...
...
libgo/go/database/sql/sql_test.go
View file @
42f20102
...
@@ -14,6 +14,7 @@ import (
...
@@ -14,6 +14,7 @@ import (
"runtime"
"runtime"
"strings"
"strings"
"sync"
"sync"
"sync/atomic"
"testing"
"testing"
"time"
"time"
)
)
...
@@ -326,9 +327,7 @@ func TestQueryContext(t *testing.T) {
...
@@ -326,9 +327,7 @@ func TestQueryContext(t *testing.T) {
// And verify that the final rows.Next() call, which hit EOF,
// And verify that the final rows.Next() call, which hit EOF,
// also closed the rows connection.
// also closed the rows connection.
if
n
:=
db
.
numFreeConns
();
n
!=
1
{
waitForFree
(
t
,
db
,
5
*
time
.
Second
,
1
)
t
.
Fatalf
(
"free conns after query hitting EOF = %d; want 1"
,
n
)
}
if
prepares
:=
numPrepares
(
t
,
db
)
-
prepares0
;
prepares
!=
1
{
if
prepares
:=
numPrepares
(
t
,
db
)
-
prepares0
;
prepares
!=
1
{
t
.
Errorf
(
"executed %d Prepare statements; want 1"
,
prepares
)
t
.
Errorf
(
"executed %d Prepare statements; want 1"
,
prepares
)
}
}
...
@@ -345,6 +344,18 @@ func waitCondition(waitFor, checkEvery time.Duration, fn func() bool) bool {
...
@@ -345,6 +344,18 @@ func waitCondition(waitFor, checkEvery time.Duration, fn func() bool) bool {
return
false
return
false
}
}
// waitForFree checks db.numFreeConns until either it equals want or
// the maxWait time elapses.
func
waitForFree
(
t
*
testing
.
T
,
db
*
DB
,
maxWait
time
.
Duration
,
want
int
)
{
var
numFree
int
if
!
waitCondition
(
maxWait
,
5
*
time
.
Millisecond
,
func
()
bool
{
numFree
=
db
.
numFreeConns
()
return
numFree
==
want
})
{
t
.
Fatalf
(
"free conns after hitting EOF = %d; want %d"
,
numFree
,
want
)
}
}
func
TestQueryContextWait
(
t
*
testing
.
T
)
{
func
TestQueryContextWait
(
t
*
testing
.
T
)
{
db
:=
newTestDB
(
t
,
"people"
)
db
:=
newTestDB
(
t
,
"people"
)
defer
closeDB
(
t
,
db
)
defer
closeDB
(
t
,
db
)
...
@@ -361,9 +372,7 @@ func TestQueryContextWait(t *testing.T) {
...
@@ -361,9 +372,7 @@ func TestQueryContextWait(t *testing.T) {
}
}
// Verify closed rows connection after error condition.
// Verify closed rows connection after error condition.
if
n
:=
db
.
numFreeConns
();
n
!=
1
{
waitForFree
(
t
,
db
,
5
*
time
.
Second
,
1
)
t
.
Fatalf
(
"free conns after query hitting EOF = %d; want 1"
,
n
)
}
if
prepares
:=
numPrepares
(
t
,
db
)
-
prepares0
;
prepares
!=
1
{
if
prepares
:=
numPrepares
(
t
,
db
)
-
prepares0
;
prepares
!=
1
{
t
.
Errorf
(
"executed %d Prepare statements; want 1"
,
prepares
)
t
.
Errorf
(
"executed %d Prepare statements; want 1"
,
prepares
)
}
}
...
@@ -388,13 +397,7 @@ func TestTxContextWait(t *testing.T) {
...
@@ -388,13 +397,7 @@ func TestTxContextWait(t *testing.T) {
t
.
Fatalf
(
"expected QueryContext to error with context deadline exceeded but returned %v"
,
err
)
t
.
Fatalf
(
"expected QueryContext to error with context deadline exceeded but returned %v"
,
err
)
}
}
var
numFree
int
waitForFree
(
t
,
db
,
5
*
time
.
Second
,
0
)
if
!
waitCondition
(
5
*
time
.
Second
,
5
*
time
.
Millisecond
,
func
()
bool
{
numFree
=
db
.
numFreeConns
()
return
numFree
==
0
})
{
t
.
Fatalf
(
"free conns after hitting EOF = %d; want 0"
,
numFree
)
}
// Ensure the dropped connection allows more connections to be made.
// Ensure the dropped connection allows more connections to be made.
// Checked on DB Close.
// Checked on DB Close.
...
@@ -471,9 +474,7 @@ func TestMultiResultSetQuery(t *testing.T) {
...
@@ -471,9 +474,7 @@ func TestMultiResultSetQuery(t *testing.T) {
// And verify that the final rows.Next() call, which hit EOF,
// And verify that the final rows.Next() call, which hit EOF,
// also closed the rows connection.
// also closed the rows connection.
if
n
:=
db
.
numFreeConns
();
n
!=
1
{
waitForFree
(
t
,
db
,
5
*
time
.
Second
,
1
)
t
.
Fatalf
(
"free conns after query hitting EOF = %d; want 1"
,
n
)
}
if
prepares
:=
numPrepares
(
t
,
db
)
-
prepares0
;
prepares
!=
1
{
if
prepares
:=
numPrepares
(
t
,
db
)
-
prepares0
;
prepares
!=
1
{
t
.
Errorf
(
"executed %d Prepare statements; want 1"
,
prepares
)
t
.
Errorf
(
"executed %d Prepare statements; want 1"
,
prepares
)
}
}
...
@@ -1135,6 +1136,24 @@ func TestQueryRowClosingStmt(t *testing.T) {
...
@@ -1135,6 +1136,24 @@ func TestQueryRowClosingStmt(t *testing.T) {
}
}
}
}
var
atomicRowsCloseHook
atomic
.
Value
// of func(*Rows, *error)
func
init
()
{
rowsCloseHook
=
func
()
func
(
*
Rows
,
*
error
)
{
fn
,
_
:=
atomicRowsCloseHook
.
Load
()
.
(
func
(
*
Rows
,
*
error
))
return
fn
}
}
func
setRowsCloseHook
(
fn
func
(
*
Rows
,
*
error
))
{
if
fn
==
nil
{
// Can't change an atomic.Value back to nil, so set it to this
// no-op func instead.
fn
=
func
(
*
Rows
,
*
error
)
{}
}
atomicRowsCloseHook
.
Store
(
fn
)
}
// Test issue 6651
// Test issue 6651
func
TestIssue6651
(
t
*
testing
.
T
)
{
func
TestIssue6651
(
t
*
testing
.
T
)
{
db
:=
newTestDB
(
t
,
"people"
)
db
:=
newTestDB
(
t
,
"people"
)
...
@@ -1147,6 +1166,7 @@ func TestIssue6651(t *testing.T) {
...
@@ -1147,6 +1166,7 @@ func TestIssue6651(t *testing.T) {
return
fmt
.
Errorf
(
want
)
return
fmt
.
Errorf
(
want
)
}
}
defer
func
()
{
rowsCursorNextHook
=
nil
}()
defer
func
()
{
rowsCursorNextHook
=
nil
}()
err
:=
db
.
QueryRow
(
"SELECT|people|name|"
)
.
Scan
(
&
v
)
err
:=
db
.
QueryRow
(
"SELECT|people|name|"
)
.
Scan
(
&
v
)
if
err
==
nil
||
err
.
Error
()
!=
want
{
if
err
==
nil
||
err
.
Error
()
!=
want
{
t
.
Errorf
(
"error = %q; want %q"
,
err
,
want
)
t
.
Errorf
(
"error = %q; want %q"
,
err
,
want
)
...
@@ -1154,10 +1174,10 @@ func TestIssue6651(t *testing.T) {
...
@@ -1154,10 +1174,10 @@ func TestIssue6651(t *testing.T) {
rowsCursorNextHook
=
nil
rowsCursorNextHook
=
nil
want
=
"error in rows.Close"
want
=
"error in rows.Close"
rowsCloseHook
=
func
(
rows
*
Rows
,
err
*
error
)
{
setRowsCloseHook
(
func
(
rows
*
Rows
,
err
*
error
)
{
*
err
=
fmt
.
Errorf
(
want
)
*
err
=
fmt
.
Errorf
(
want
)
}
}
)
defer
func
()
{
rowsCloseHook
=
nil
}(
)
defer
setRowsCloseHook
(
nil
)
err
=
db
.
QueryRow
(
"SELECT|people|name|"
)
.
Scan
(
&
v
)
err
=
db
.
QueryRow
(
"SELECT|people|name|"
)
.
Scan
(
&
v
)
if
err
==
nil
||
err
.
Error
()
!=
want
{
if
err
==
nil
||
err
.
Error
()
!=
want
{
t
.
Errorf
(
"error = %q; want %q"
,
err
,
want
)
t
.
Errorf
(
"error = %q; want %q"
,
err
,
want
)
...
@@ -1830,7 +1850,9 @@ func TestStmtCloseDeps(t *testing.T) {
...
@@ -1830,7 +1850,9 @@ func TestStmtCloseDeps(t *testing.T) {
db
.
dumpDeps
(
t
)
db
.
dumpDeps
(
t
)
}
}
if
len
(
stmt
.
css
)
>
nquery
{
if
!
waitCondition
(
5
*
time
.
Second
,
5
*
time
.
Millisecond
,
func
()
bool
{
return
len
(
stmt
.
css
)
<=
nquery
})
{
t
.
Errorf
(
"len(stmt.css) = %d; want <= %d"
,
len
(
stmt
.
css
),
nquery
)
t
.
Errorf
(
"len(stmt.css) = %d; want <= %d"
,
len
(
stmt
.
css
),
nquery
)
}
}
...
@@ -2576,10 +2598,10 @@ func TestIssue6081(t *testing.T) {
...
@@ -2576,10 +2598,10 @@ func TestIssue6081(t *testing.T) {
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatal
(
err
)
t
.
Fatal
(
err
)
}
}
rowsCloseHook
=
func
(
rows
*
Rows
,
err
*
error
)
{
setRowsCloseHook
(
func
(
rows
*
Rows
,
err
*
error
)
{
*
err
=
driver
.
ErrBadConn
*
err
=
driver
.
ErrBadConn
}
}
)
defer
func
()
{
rowsCloseHook
=
nil
}(
)
defer
setRowsCloseHook
(
nil
)
for
i
:=
0
;
i
<
10
;
i
++
{
for
i
:=
0
;
i
<
10
;
i
++
{
rows
,
err
:=
stmt
.
Query
()
rows
,
err
:=
stmt
.
Query
()
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -2642,7 +2664,10 @@ func TestIssue18429(t *testing.T) {
...
@@ -2642,7 +2664,10 @@ func TestIssue18429(t *testing.T) {
if
err
!=
nil
{
if
err
!=
nil
{
return
return
}
}
rows
,
err
:=
tx
.
QueryContext
(
ctx
,
"WAIT|"
+
qwait
+
"|SELECT|people|name|"
)
// This is expected to give a cancel error many, but not all the time.
// Test failure will happen with a panic or other race condition being
// reported.
rows
,
_
:=
tx
.
QueryContext
(
ctx
,
"WAIT|"
+
qwait
+
"|SELECT|people|name|"
)
if
rows
!=
nil
{
if
rows
!=
nil
{
rows
.
Close
()
rows
.
Close
()
}
}
...
@@ -2655,6 +2680,56 @@ func TestIssue18429(t *testing.T) {
...
@@ -2655,6 +2680,56 @@ func TestIssue18429(t *testing.T) {
time
.
Sleep
(
milliWait
*
3
*
time
.
Millisecond
)
time
.
Sleep
(
milliWait
*
3
*
time
.
Millisecond
)
}
}
// TestIssue18719 closes the context right before use. The sql.driverConn
// will nil out the ci on close in a lock, but if another process uses it right after
// it will panic with on the nil ref.
//
// See https://golang.org/cl/35550 .
func
TestIssue18719
(
t
*
testing
.
T
)
{
db
:=
newTestDB
(
t
,
"people"
)
defer
closeDB
(
t
,
db
)
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
defer
cancel
()
tx
,
err
:=
db
.
BeginTx
(
ctx
,
nil
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
hookTxGrabConn
=
func
()
{
cancel
()
// Wait for the context to cancel and tx to rollback.
for
tx
.
isDone
()
==
false
{
time
.
Sleep
(
time
.
Millisecond
*
3
)
}
}
defer
func
()
{
hookTxGrabConn
=
nil
}()
// This call will grab the connection and cancel the context
// after it has done so. Code after must deal with the canceled state.
rows
,
err
:=
tx
.
QueryContext
(
ctx
,
"SELECT|people|name|"
)
if
err
!=
nil
{
rows
.
Close
()
t
.
Fatalf
(
"expected error %v but got %v"
,
nil
,
err
)
}
// Rows may be ignored because it will be closed when the context is canceled.
// Do not explicitly rollback. The rollback will happen from the
// canceled context.
// Wait for connections to return to pool.
var
numOpen
int
if
!
waitCondition
(
5
*
time
.
Second
,
5
*
time
.
Millisecond
,
func
()
bool
{
numOpen
=
db
.
numOpenConns
()
return
numOpen
==
0
})
{
t
.
Fatalf
(
"open conns after hitting EOF = %d; want 0"
,
numOpen
)
}
}
func
TestConcurrency
(
t
*
testing
.
T
)
{
func
TestConcurrency
(
t
*
testing
.
T
)
{
doConcurrentTest
(
t
,
new
(
concurrentDBQueryTest
))
doConcurrentTest
(
t
,
new
(
concurrentDBQueryTest
))
doConcurrentTest
(
t
,
new
(
concurrentDBExecTest
))
doConcurrentTest
(
t
,
new
(
concurrentDBExecTest
))
...
...
libgo/go/go/printer/nodes.go
View file @
42f20102
...
@@ -733,7 +733,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
...
@@ -733,7 +733,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
case
*
ast
.
FuncLit
:
case
*
ast
.
FuncLit
:
p
.
expr
(
x
.
Type
)
p
.
expr
(
x
.
Type
)
p
.
adjBlock
(
p
.
distanceFrom
(
x
.
Type
.
Pos
()),
blank
,
x
.
Body
)
p
.
funcBody
(
p
.
distanceFrom
(
x
.
Type
.
Pos
()),
blank
,
x
.
Body
)
case
*
ast
.
ParenExpr
:
case
*
ast
.
ParenExpr
:
if
_
,
hasParens
:=
x
.
X
.
(
*
ast
.
ParenExpr
);
hasParens
{
if
_
,
hasParens
:=
x
.
X
.
(
*
ast
.
ParenExpr
);
hasParens
{
...
@@ -825,6 +825,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
...
@@ -825,6 +825,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
if
x
.
Type
!=
nil
{
if
x
.
Type
!=
nil
{
p
.
expr1
(
x
.
Type
,
token
.
HighestPrec
,
depth
)
p
.
expr1
(
x
.
Type
,
token
.
HighestPrec
,
depth
)
}
}
p
.
level
++
p
.
print
(
x
.
Lbrace
,
token
.
LBRACE
)
p
.
print
(
x
.
Lbrace
,
token
.
LBRACE
)
p
.
exprList
(
x
.
Lbrace
,
x
.
Elts
,
1
,
commaTerm
,
x
.
Rbrace
)
p
.
exprList
(
x
.
Lbrace
,
x
.
Elts
,
1
,
commaTerm
,
x
.
Rbrace
)
// do not insert extra line break following a /*-style comment
// do not insert extra line break following a /*-style comment
...
@@ -837,6 +838,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
...
@@ -837,6 +838,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
mode
|=
noExtraBlank
mode
|=
noExtraBlank
}
}
p
.
print
(
mode
,
x
.
Rbrace
,
token
.
RBRACE
,
mode
)
p
.
print
(
mode
,
x
.
Rbrace
,
token
.
RBRACE
,
mode
)
p
.
level
--
case
*
ast
.
Ellipsis
:
case
*
ast
.
Ellipsis
:
p
.
print
(
token
.
ELLIPSIS
)
p
.
print
(
token
.
ELLIPSIS
)
...
@@ -1557,18 +1559,23 @@ func (p *printer) bodySize(b *ast.BlockStmt, maxSize int) int {
...
@@ -1557,18 +1559,23 @@ func (p *printer) bodySize(b *ast.BlockStmt, maxSize int) int {
return
bodySize
return
bodySize
}
}
// adjBlock prints an "adjacent" block (e.g., a for-loop or function body) following
// funcBody prints a function body following a function header of given headerSize.
// a header (e.g., a for-loop control clause or function signature) of given headerSize.
// If the header's and block's size are "small enough" and the block is "simple enough",
// If the header's and block's size are "small enough" and the block is "simple enough",
// the block is printed on the current line, without line breaks, spaced from the header
// the block is printed on the current line, without line breaks, spaced from the header
// by sep. Otherwise the block's opening "{" is printed on the current line, followed by
// by sep. Otherwise the block's opening "{" is printed on the current line, followed by
// lines for the block's statements and its closing "}".
// lines for the block's statements and its closing "}".
//
//
func
(
p
*
printer
)
adjBlock
(
headerSize
int
,
sep
whiteSpace
,
b
*
ast
.
BlockStmt
)
{
func
(
p
*
printer
)
funcBody
(
headerSize
int
,
sep
whiteSpace
,
b
*
ast
.
BlockStmt
)
{
if
b
==
nil
{
if
b
==
nil
{
return
return
}
}
// save/restore composite literal nesting level
defer
func
(
level
int
)
{
p
.
level
=
level
}(
p
.
level
)
p
.
level
=
0
const
maxSize
=
100
const
maxSize
=
100
if
headerSize
+
p
.
bodySize
(
b
,
maxSize
)
<=
maxSize
{
if
headerSize
+
p
.
bodySize
(
b
,
maxSize
)
<=
maxSize
{
p
.
print
(
sep
,
b
.
Lbrace
,
token
.
LBRACE
)
p
.
print
(
sep
,
b
.
Lbrace
,
token
.
LBRACE
)
...
@@ -1613,7 +1620,7 @@ func (p *printer) funcDecl(d *ast.FuncDecl) {
...
@@ -1613,7 +1620,7 @@ func (p *printer) funcDecl(d *ast.FuncDecl) {
}
}
p
.
expr
(
d
.
Name
)
p
.
expr
(
d
.
Name
)
p
.
signature
(
d
.
Type
.
Params
,
d
.
Type
.
Results
)
p
.
signature
(
d
.
Type
.
Params
,
d
.
Type
.
Results
)
p
.
adjBlock
(
p
.
distanceFrom
(
d
.
Pos
()),
vtab
,
d
.
Body
)
p
.
funcBody
(
p
.
distanceFrom
(
d
.
Pos
()),
vtab
,
d
.
Body
)
}
}
func
(
p
*
printer
)
decl
(
decl
ast
.
Decl
)
{
func
(
p
*
printer
)
decl
(
decl
ast
.
Decl
)
{
...
...
libgo/go/go/printer/printer.go
View file @
42f20102
...
@@ -58,6 +58,7 @@ type printer struct {
...
@@ -58,6 +58,7 @@ type printer struct {
// Current state
// Current state
output
[]
byte
// raw printer result
output
[]
byte
// raw printer result
indent
int
// current indentation
indent
int
// current indentation
level
int
// level == 0: outside composite literal; level > 0: inside composite literal
mode
pmode
// current printer mode
mode
pmode
// current printer mode
impliedSemi
bool
// if set, a linebreak implies a semicolon
impliedSemi
bool
// if set, a linebreak implies a semicolon
lastTok
token
.
Token
// last token printed (token.ILLEGAL if it's whitespace)
lastTok
token
.
Token
// last token printed (token.ILLEGAL if it's whitespace)
...
@@ -744,15 +745,19 @@ func (p *printer) intersperseComments(next token.Position, tok token.Token) (wro
...
@@ -744,15 +745,19 @@ func (p *printer) intersperseComments(next token.Position, tok token.Token) (wro
// follows on the same line but is not a comma, and not a "closing"
// follows on the same line but is not a comma, and not a "closing"
// token immediately following its corresponding "opening" token,
// token immediately following its corresponding "opening" token,
// add an extra separator unless explicitly disabled. Use a blank
// add an extra separator unless explicitly disabled. Use a blank
// as separator unless we have pending linebreaks and they are not
// as separator unless we have pending linebreaks, they are not
// disabled, in which case we want a linebreak (issue 15137).
// disabled, and we are outside a composite literal, in which case
// we want a linebreak (issue 15137).
// TODO(gri) This has become overly complicated. We should be able
// to track whether we're inside an expression or statement and
// use that information to decide more directly.
needsLinebreak
:=
false
needsLinebreak
:=
false
if
p
.
mode
&
noExtraBlank
==
0
&&
if
p
.
mode
&
noExtraBlank
==
0
&&
last
.
Text
[
1
]
==
'*'
&&
p
.
lineFor
(
last
.
Pos
())
==
next
.
Line
&&
last
.
Text
[
1
]
==
'*'
&&
p
.
lineFor
(
last
.
Pos
())
==
next
.
Line
&&
tok
!=
token
.
COMMA
&&
tok
!=
token
.
COMMA
&&
(
tok
!=
token
.
RPAREN
||
p
.
prevOpen
==
token
.
LPAREN
)
&&
(
tok
!=
token
.
RPAREN
||
p
.
prevOpen
==
token
.
LPAREN
)
&&
(
tok
!=
token
.
RBRACK
||
p
.
prevOpen
==
token
.
LBRACK
)
{
(
tok
!=
token
.
RBRACK
||
p
.
prevOpen
==
token
.
LBRACK
)
{
if
p
.
containsLinebreak
()
&&
p
.
mode
&
noExtraLinebreak
==
0
{
if
p
.
containsLinebreak
()
&&
p
.
mode
&
noExtraLinebreak
==
0
&&
p
.
level
==
0
{
needsLinebreak
=
true
needsLinebreak
=
true
}
else
{
}
else
{
p
.
writeByte
(
' '
,
1
)
p
.
writeByte
(
' '
,
1
)
...
...
libgo/go/go/printer/testdata/comments2.golden
View file @
42f20102
...
@@ -103,3 +103,62 @@ label:
...
@@ -103,3 +103,62 @@ label:
mask
:=
uint64
(
1
)<<
c
-
1
//
Allocation
mask
mask
:=
uint64
(
1
)<<
c
-
1
//
Allocation
mask
used
:=
atomic
.
LoadUint64
(&
h
.
used
)
//
Current
allocations
used
:=
atomic
.
LoadUint64
(&
h
.
used
)
//
Current
allocations
}
}
//
Test
cases
for
issue
18782
var
_
=
[][]
int
{
/*
a
,
b
,
c
,
d
,
e
*/
/*
a
*/
{
0
,
0
,
0
,
0
,
0
},
/*
b
*/
{
0
,
5
,
4
,
4
,
4
},
/*
c
*/
{
0
,
4
,
5
,
4
,
4
},
/*
d
*/
{
0
,
4
,
4
,
5
,
4
},
/*
e
*/
{
0
,
4
,
4
,
4
,
5
},
}
var
_
=
T
{
/*
a
*/
0
}
var
_
=
T
{
/*
a
*/
/*
b
*/
0
}
var
_
=
T
{
/*
a
*/
/*
b
*/
/*
c
*/
0
,
}
var
_
=
T
{
/*
a
*/
/*
b
*/
/*
c
*/
/*
d
*/
0
,
}
var
_
=
T
{
/*
a
*/
/*
b
*/
0
,
}
var
_
=
T
{
/*
a
*/
{}}
var
_
=
T
{
/*
a
*/
/*
b
*/
{}}
var
_
=
T
{
/*
a
*/
/*
b
*/
/*
c
*/
{},
}
var
_
=
T
{
/*
a
*/
/*
b
*/
/*
c
*/
/*
d
*/
{},
}
var
_
=
T
{
/*
a
*/
/*
b
*/
{},
}
var
_
=
[]
T
{
func
()
{
var
_
=
[][]
int
{
/*
a
,
b
,
c
,
d
,
e
*/
/*
a
*/
{
0
,
0
,
0
,
0
,
0
},
/*
b
*/
{
0
,
5
,
4
,
4
,
4
},
/*
c
*/
{
0
,
4
,
5
,
4
,
4
},
/*
d
*/
{
0
,
4
,
4
,
5
,
4
},
/*
e
*/
{
0
,
4
,
4
,
4
,
5
},
}
},
}
libgo/go/go/printer/testdata/comments2.input
View file @
42f20102
...
@@ -103,3 +103,66 @@ label:
...
@@ -103,3 +103,66 @@ label:
mask
:=
uint64
(
1
)<<
c
-
1
//
Allocation
mask
mask
:=
uint64
(
1
)<<
c
-
1
//
Allocation
mask
used
:=
atomic
.
LoadUint64
(&
h
.
used
)
//
Current
allocations
used
:=
atomic
.
LoadUint64
(&
h
.
used
)
//
Current
allocations
}
}
//
Test
cases
for
issue
18782
var
_
=
[][]
int
{
/*
a
,
b
,
c
,
d
,
e
*/
/*
a
*/
{
0
,
0
,
0
,
0
,
0
},
/*
b
*/
{
0
,
5
,
4
,
4
,
4
},
/*
c
*/
{
0
,
4
,
5
,
4
,
4
},
/*
d
*/
{
0
,
4
,
4
,
5
,
4
},
/*
e
*/
{
0
,
4
,
4
,
4
,
5
},
}
var
_
=
T
{
/*
a
*/
0
,
}
var
_
=
T
{
/*
a
*/
/*
b
*/
0
,
}
var
_
=
T
{
/*
a
*/
/*
b
*/
/*
c
*/
0
,
}
var
_
=
T
{
/*
a
*/
/*
b
*/
/*
c
*/
/*
d
*/
0
,
}
var
_
=
T
{
/*
a
*/
/*
b
*/
0
,
}
var
_
=
T
{
/*
a
*/
{},
}
var
_
=
T
{
/*
a
*/
/*
b
*/
{},
}
var
_
=
T
{
/*
a
*/
/*
b
*/
/*
c
*/
{},
}
var
_
=
T
{
/*
a
*/
/*
b
*/
/*
c
*/
/*
d
*/
{},
}
var
_
=
T
{
/*
a
*/
/*
b
*/
{},
}
var
_
=
[]
T
{
func
()
{
var
_
=
[][]
int
{
/*
a
,
b
,
c
,
d
,
e
*/
/*
a
*/
{
0
,
0
,
0
,
0
,
0
},
/*
b
*/
{
0
,
5
,
4
,
4
,
4
},
/*
c
*/
{
0
,
4
,
5
,
4
,
4
},
/*
d
*/
{
0
,
4
,
4
,
5
,
4
},
/*
e
*/
{
0
,
4
,
4
,
4
,
5
},
}
},
}
libgo/go/net/http/client.go
View file @
42f20102
...
@@ -413,11 +413,12 @@ func (c *Client) checkRedirect(req *Request, via []*Request) error {
...
@@ -413,11 +413,12 @@ func (c *Client) checkRedirect(req *Request, via []*Request) error {
// redirectBehavior describes what should happen when the
// redirectBehavior describes what should happen when the
// client encounters a 3xx status code from the server
// client encounters a 3xx status code from the server
func
redirectBehavior
(
reqMethod
string
,
resp
*
Response
,
ireq
*
Request
)
(
redirectMethod
string
,
shouldRedirect
bool
)
{
func
redirectBehavior
(
reqMethod
string
,
resp
*
Response
,
ireq
*
Request
)
(
redirectMethod
string
,
shouldRedirect
,
includeBody
bool
)
{
switch
resp
.
StatusCode
{
switch
resp
.
StatusCode
{
case
301
,
302
,
303
:
case
301
,
302
,
303
:
redirectMethod
=
reqMethod
redirectMethod
=
reqMethod
shouldRedirect
=
true
shouldRedirect
=
true
includeBody
=
false
// RFC 2616 allowed automatic redirection only with GET and
// RFC 2616 allowed automatic redirection only with GET and
// HEAD requests. RFC 7231 lifts this restriction, but we still
// HEAD requests. RFC 7231 lifts this restriction, but we still
...
@@ -429,6 +430,7 @@ func redirectBehavior(reqMethod string, resp *Response, ireq *Request) (redirect
...
@@ -429,6 +430,7 @@ func redirectBehavior(reqMethod string, resp *Response, ireq *Request) (redirect
case
307
,
308
:
case
307
,
308
:
redirectMethod
=
reqMethod
redirectMethod
=
reqMethod
shouldRedirect
=
true
shouldRedirect
=
true
includeBody
=
true
// Treat 307 and 308 specially, since they're new in
// Treat 307 and 308 specially, since they're new in
// Go 1.8, and they also require re-sending the request body.
// Go 1.8, and they also require re-sending the request body.
...
@@ -449,7 +451,7 @@ func redirectBehavior(reqMethod string, resp *Response, ireq *Request) (redirect
...
@@ -449,7 +451,7 @@ func redirectBehavior(reqMethod string, resp *Response, ireq *Request) (redirect
shouldRedirect
=
false
shouldRedirect
=
false
}
}
}
}
return
redirectMethod
,
shouldRedirect
return
redirectMethod
,
shouldRedirect
,
includeBody
}
}
// Do sends an HTTP request and returns an HTTP response, following
// Do sends an HTTP request and returns an HTTP response, following
...
@@ -492,11 +494,14 @@ func (c *Client) Do(req *Request) (*Response, error) {
...
@@ -492,11 +494,14 @@ func (c *Client) Do(req *Request) (*Response, error) {
}
}
var
(
var
(
deadline
=
c
.
deadline
()
deadline
=
c
.
deadline
()
reqs
[]
*
Request
reqs
[]
*
Request
resp
*
Response
resp
*
Response
copyHeaders
=
c
.
makeHeadersCopier
(
req
)
copyHeaders
=
c
.
makeHeadersCopier
(
req
)
// Redirect behavior:
redirectMethod
string
redirectMethod
string
includeBody
bool
)
)
uerr
:=
func
(
err
error
)
error
{
uerr
:=
func
(
err
error
)
error
{
req
.
closeBody
()
req
.
closeBody
()
...
@@ -534,7 +539,7 @@ func (c *Client) Do(req *Request) (*Response, error) {
...
@@ -534,7 +539,7 @@ func (c *Client) Do(req *Request) (*Response, error) {
Cancel
:
ireq
.
Cancel
,
Cancel
:
ireq
.
Cancel
,
ctx
:
ireq
.
ctx
,
ctx
:
ireq
.
ctx
,
}
}
if
ireq
.
GetBody
!=
nil
{
if
i
ncludeBody
&&
i
req
.
GetBody
!=
nil
{
req
.
Body
,
err
=
ireq
.
GetBody
()
req
.
Body
,
err
=
ireq
.
GetBody
()
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
uerr
(
err
)
return
nil
,
uerr
(
err
)
...
@@ -598,7 +603,7 @@ func (c *Client) Do(req *Request) (*Response, error) {
...
@@ -598,7 +603,7 @@ func (c *Client) Do(req *Request) (*Response, error) {
}
}
var
shouldRedirect
bool
var
shouldRedirect
bool
redirectMethod
,
shouldRedirect
=
redirectBehavior
(
req
.
Method
,
resp
,
reqs
[
0
])
redirectMethod
,
shouldRedirect
,
includeBody
=
redirectBehavior
(
req
.
Method
,
resp
,
reqs
[
0
])
if
!
shouldRedirect
{
if
!
shouldRedirect
{
return
resp
,
nil
return
resp
,
nil
}
}
...
...
libgo/go/net/http/client_test.go
View file @
42f20102
...
@@ -360,25 +360,25 @@ func TestPostRedirects(t *testing.T) {
...
@@ -360,25 +360,25 @@ func TestPostRedirects(t *testing.T) {
wantSegments
:=
[]
string
{
wantSegments
:=
[]
string
{
`POST / "first"`
,
`POST / "first"`
,
`POST /?code=301&next=302 "c301"`
,
`POST /?code=301&next=302 "c301"`
,
`GET /?code=302 "
c301
"`
,
`GET /?code=302 ""`
,
`GET / "
c301
"`
,
`GET / ""`
,
`POST /?code=302&next=302 "c302"`
,
`POST /?code=302&next=302 "c302"`
,
`GET /?code=302 "
c302
"`
,
`GET /?code=302 ""`
,
`GET / "
c302
"`
,
`GET / ""`
,
`POST /?code=303&next=301 "c303wc301"`
,
`POST /?code=303&next=301 "c303wc301"`
,
`GET /?code=301 "
c303wc301
"`
,
`GET /?code=301 ""`
,
`GET / "
c303wc301
"`
,
`GET / ""`
,
`POST /?code=304 "c304"`
,
`POST /?code=304 "c304"`
,
`POST /?code=305 "c305"`
,
`POST /?code=305 "c305"`
,
`POST /?code=307&next=303,308,302 "c307"`
,
`POST /?code=307&next=303,308,302 "c307"`
,
`POST /?code=303&next=308,302 "c307"`
,
`POST /?code=303&next=308,302 "c307"`
,
`GET /?code=308&next=302 "
c307
"`
,
`GET /?code=308&next=302 ""`
,
`GET /?code=302 "c307"`
,
`GET /?code=302 "c307"`
,
`GET / "
c307
"`
,
`GET / ""`
,
`POST /?code=308&next=302,301 "c308"`
,
`POST /?code=308&next=302,301 "c308"`
,
`POST /?code=302&next=301 "c308"`
,
`POST /?code=302&next=301 "c308"`
,
`GET /?code=301 "
c308
"`
,
`GET /?code=301 ""`
,
`GET / "
c308
"`
,
`GET / ""`
,
`POST /?code=404 "c404"`
,
`POST /?code=404 "c404"`
,
}
}
want
:=
strings
.
Join
(
wantSegments
,
"
\n
"
)
want
:=
strings
.
Join
(
wantSegments
,
"
\n
"
)
...
@@ -399,20 +399,20 @@ func TestDeleteRedirects(t *testing.T) {
...
@@ -399,20 +399,20 @@ func TestDeleteRedirects(t *testing.T) {
wantSegments
:=
[]
string
{
wantSegments
:=
[]
string
{
`DELETE / "first"`
,
`DELETE / "first"`
,
`DELETE /?code=301&next=302,308 "c301"`
,
`DELETE /?code=301&next=302,308 "c301"`
,
`GET /?code=302&next=308 "
c301
"`
,
`GET /?code=302&next=308 ""`
,
`GET /?code=308 "
c301
"`
,
`GET /?code=308 ""`
,
`GET / "c301"`
,
`GET / "c301"`
,
`DELETE /?code=302&next=302 "c302"`
,
`DELETE /?code=302&next=302 "c302"`
,
`GET /?code=302 "
c302
"`
,
`GET /?code=302 ""`
,
`GET / "
c302
"`
,
`GET / ""`
,
`DELETE /?code=303 "c303"`
,
`DELETE /?code=303 "c303"`
,
`GET / "
c303
"`
,
`GET / ""`
,
`DELETE /?code=307&next=301,308,303,302,304 "c307"`
,
`DELETE /?code=307&next=301,308,303,302,304 "c307"`
,
`DELETE /?code=301&next=308,303,302,304 "c307"`
,
`DELETE /?code=301&next=308,303,302,304 "c307"`
,
`GET /?code=308&next=303,302,304 "
c307
"`
,
`GET /?code=308&next=303,302,304 ""`
,
`GET /?code=303&next=302,304 "c307"`
,
`GET /?code=303&next=302,304 "c307"`
,
`GET /?code=302&next=304 "
c307
"`
,
`GET /?code=302&next=304 ""`
,
`GET /?code=304 "
c307
"`
,
`GET /?code=304 ""`
,
`DELETE /?code=308&next=307 "c308"`
,
`DELETE /?code=308&next=307 "c308"`
,
`DELETE /?code=307 "c308"`
,
`DELETE /?code=307 "c308"`
,
`DELETE / "c308"`
,
`DELETE / "c308"`
,
...
@@ -432,7 +432,11 @@ func testRedirectsByMethod(t *testing.T, method string, table []redirectTest, wa
...
@@ -432,7 +432,11 @@ func testRedirectsByMethod(t *testing.T, method string, table []redirectTest, wa
ts
=
httptest
.
NewServer
(
HandlerFunc
(
func
(
w
ResponseWriter
,
r
*
Request
)
{
ts
=
httptest
.
NewServer
(
HandlerFunc
(
func
(
w
ResponseWriter
,
r
*
Request
)
{
log
.
Lock
()
log
.
Lock
()
slurp
,
_
:=
ioutil
.
ReadAll
(
r
.
Body
)
slurp
,
_
:=
ioutil
.
ReadAll
(
r
.
Body
)
fmt
.
Fprintf
(
&
log
.
Buffer
,
"%s %s %q
\n
"
,
r
.
Method
,
r
.
RequestURI
,
slurp
)
fmt
.
Fprintf
(
&
log
.
Buffer
,
"%s %s %q"
,
r
.
Method
,
r
.
RequestURI
,
slurp
)
if
cl
:=
r
.
Header
.
Get
(
"Content-Length"
);
r
.
Method
==
"GET"
&&
len
(
slurp
)
==
0
&&
(
r
.
ContentLength
!=
0
||
cl
!=
""
)
{
fmt
.
Fprintf
(
&
log
.
Buffer
,
" (but with body=%T, content-length = %v, %q)"
,
r
.
Body
,
r
.
ContentLength
,
cl
)
}
log
.
WriteByte
(
'\n'
)
log
.
Unlock
()
log
.
Unlock
()
urlQuery
:=
r
.
URL
.
Query
()
urlQuery
:=
r
.
URL
.
Query
()
if
v
:=
urlQuery
.
Get
(
"code"
);
v
!=
""
{
if
v
:=
urlQuery
.
Get
(
"code"
);
v
!=
""
{
...
@@ -475,7 +479,24 @@ func testRedirectsByMethod(t *testing.T, method string, table []redirectTest, wa
...
@@ -475,7 +479,24 @@ func testRedirectsByMethod(t *testing.T, method string, table []redirectTest, wa
want
=
strings
.
TrimSpace
(
want
)
want
=
strings
.
TrimSpace
(
want
)
if
got
!=
want
{
if
got
!=
want
{
t
.
Errorf
(
"Log differs.
\n
Got:
\n
%s
\n
Want:
\n
%s
\n
"
,
got
,
want
)
got
,
want
,
lines
:=
removeCommonLines
(
got
,
want
)
t
.
Errorf
(
"Log differs after %d common lines.
\n\n
Got:
\n
%s
\n\n
Want:
\n
%s
\n
"
,
lines
,
got
,
want
)
}
}
func
removeCommonLines
(
a
,
b
string
)
(
asuffix
,
bsuffix
string
,
commonLines
int
)
{
for
{
nl
:=
strings
.
IndexByte
(
a
,
'\n'
)
if
nl
<
0
{
return
a
,
b
,
commonLines
}
line
:=
a
[
:
nl
+
1
]
if
!
strings
.
HasPrefix
(
b
,
line
)
{
return
a
,
b
,
commonLines
}
commonLines
++
a
=
a
[
len
(
line
)
:
]
b
=
b
[
len
(
line
)
:
]
}
}
}
}
...
...
libgo/go/net/http/serve_test.go
View file @
42f20102
...
@@ -5277,7 +5277,7 @@ func TestServerHijackGetsBackgroundByte_big(t *testing.T) {
...
@@ -5277,7 +5277,7 @@ func TestServerHijackGetsBackgroundByte_big(t *testing.T) {
defer
conn
.
Close
()
defer
conn
.
Close
()
slurp
,
err
:=
ioutil
.
ReadAll
(
buf
.
Reader
)
slurp
,
err
:=
ioutil
.
ReadAll
(
buf
.
Reader
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Error
(
"Copy: %v"
,
err
)
t
.
Error
f
(
"Copy: %v"
,
err
)
}
}
allX
:=
true
allX
:=
true
for
_
,
v
:=
range
slurp
{
for
_
,
v
:=
range
slurp
{
...
...
libgo/merge.sh
View file @
42f20102
...
@@ -71,7 +71,9 @@ merge() {
...
@@ -71,7 +71,9 @@ merge() {
elif
test
-f
${
old
}
;
then
elif
test
-f
${
old
}
;
then
# The file exists in the old version.
# The file exists in the old version.
if
!
test
-f
${
libgo
}
;
then
if
!
test
-f
${
libgo
}
;
then
echo
"merge.sh:
$name
: skipping: exists in old and new git, but not in libgo"
if
!
cmp
-s
${
old
}
${
new
}
;
then
echo
"merge.sh:
$name
: skipping: exists in old and new git, but not in libgo"
fi
continue
continue
fi
fi
if
cmp
-s
${
old
}
${
libgo
}
;
then
if
cmp
-s
${
old
}
${
libgo
}
;
then
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment