Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
caddy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
caddy
Commits
6c6e0e3f
Commit
6c6e0e3f
authored
May 26, 2015
by
Abiola Ibrahim
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Git: More tests. Code refactor.
parent
6f05794b
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
279 additions
and
20 deletions
+279
-20
config/setup/git.go
config/setup/git.go
+2
-17
config/setup/git_test.go
config/setup/git_test.go
+71
-3
middleware/git/git.go
middleware/git/git.go
+3
-0
middleware/git/git_test.go
middleware/git/git_test.go
+33
-0
middleware/git/service.go
middleware/git/service.go
+110
-0
middleware/git/service_test.go
middleware/git/service_test.go
+60
-0
No files found.
config/setup/git.go
View file @
6c6e0e3f
...
...
@@ -2,7 +2,6 @@ package setup
import
(
"fmt"
"log"
"net/url"
"path/filepath"
"runtime"
...
...
@@ -22,22 +21,8 @@ func Git(c *Controller) (middleware.Middleware, error) {
}
c
.
Startup
=
append
(
c
.
Startup
,
func
()
error
{
// Startup functions are blocking; start
// service routine in background
go
func
()
{
for
{
time
.
Sleep
(
repo
.
Interval
)
err
:=
repo
.
Pull
()
if
err
!=
nil
{
if
git
.
Logger
==
nil
{
log
.
Println
(
err
)
}
else
{
git
.
Logger
.
Println
(
err
)
}
}
}
}()
// Start service routine in background
git
.
Start
(
repo
)
// Do a pull right away to return error
return
repo
.
Pull
()
...
...
config/setup/git_test.go
View file @
6c6e0e3f
package
setup
import
(
"io/ioutil"
"log"
"strings"
"testing"
"time"
...
...
@@ -13,18 +16,83 @@ func init() {
git
.
SetOS
(
gittest
.
FakeOS
)
}
func
check
(
t
*
testing
.
T
,
err
error
)
{
if
err
!=
nil
{
t
.
Errorf
(
"Expected no errors, but got: %v"
,
err
)
}
}
func
TestGit
(
t
*
testing
.
T
)
{
c
:=
newTestController
(
`git git@github.com:mholt/caddy.git`
)
mid
,
err
:=
Git
(
c
)
if
err
!=
nil
{
t
.
Errorf
(
"Expected no errors, but got: %v"
,
err
)
}
check
(
t
,
err
)
if
mid
!=
nil
{
t
.
Fatal
(
"Git middleware is a background service and expected to be nil."
)
}
}
func
TestIntervals
(
t
*
testing
.
T
)
{
tests
:=
[]
string
{
`git git@github.com:user/repo { interval 10 }`
,
`git git@github.com:user/repo { interval 5 }`
,
`git git@github.com:user/repo { interval 2 }`
,
`git git@github.com:user/repo { interval 1 }`
,
`git git@github.com:user/repo { interval 6 }`
,
}
for
i
,
test
:=
range
tests
{
git
.
Logger
=
nil
c1
:=
newTestController
(
test
)
repo
,
err
:=
gitParse
(
c1
)
check
(
t
,
err
)
c2
:=
newTestController
(
test
)
_
,
err
=
Git
(
c2
)
check
(
t
,
err
)
// start startup services
err
=
c2
.
Startup
[
0
]()
check
(
t
,
err
)
// wait for first background pull
time
.
Sleep
(
time
.
Millisecond
*
100
)
// switch logger to test file
logFile
:=
gittest
.
Open
(
"file"
)
git
.
Logger
=
log
.
New
(
logFile
,
""
,
0
)
// sleep for the interval
time
.
Sleep
(
repo
.
Interval
)
// get log output
out
,
err
:=
ioutil
.
ReadAll
(
logFile
)
check
(
t
,
err
)
// if greater than minimum interval
if
repo
.
Interval
>=
time
.
Second
*
5
{
expected
:=
`https://github.com/user/repo.git pulled.
No new changes.`
// ensure pull is done by tracing the output
if
expected
!=
strings
.
TrimSpace
(
string
(
out
))
{
t
.
Errorf
(
"Test %v: Expected %v found %v"
,
i
,
expected
,
string
(
out
))
}
}
else
{
// ensure pull is ignored by confirming no output
if
string
(
out
)
!=
""
{
t
.
Errorf
(
"Test %v: Expected no output but found %v"
,
i
,
string
(
out
))
}
}
// stop background thread monitor
git
.
Monitor
.
StopAndWait
(
repo
.
URL
,
1
)
}
}
func
TestGitParse
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
input
string
...
...
middleware/git/git.go
View file @
6c6e0e3f
...
...
@@ -33,6 +33,9 @@ var initMutex = sync.Mutex{}
// Logger is used to log errors; if nil, the default log.Logger is used.
var
Logger
*
log
.
Logger
// Monitor listens for halt signal to stop repositories from auto pulling.
var
Monitor
=
&
monitor
{}
// logger is an helper function to retrieve the available logger
func
logger
()
*
log
.
Logger
{
if
Logger
==
nil
{
...
...
middleware/git/git_test.go
View file @
6c6e0e3f
...
...
@@ -139,6 +139,39 @@ Command echo Hello successful.
}
}
// timeout checks
timeoutTests
:=
[]
struct
{
repo
*
Repo
shouldPull
bool
}{
{
&
Repo
{
Interval
:
time
.
Millisecond
*
4900
},
false
},
{
&
Repo
{
Interval
:
time
.
Millisecond
*
1
},
false
},
{
&
Repo
{
Interval
:
time
.
Second
*
5
},
true
},
{
&
Repo
{
Interval
:
time
.
Second
*
10
},
true
},
}
for
i
,
r
:=
range
timeoutTests
{
r
.
repo
=
createRepo
(
r
.
repo
)
err
:=
r
.
repo
.
Prepare
()
check
(
t
,
err
)
err
=
r
.
repo
.
Pull
()
check
(
t
,
err
)
before
:=
r
.
repo
.
lastPull
time
.
Sleep
(
r
.
repo
.
Interval
)
err
=
r
.
repo
.
Pull
()
after
:=
r
.
repo
.
lastPull
check
(
t
,
err
)
expected
:=
after
.
After
(
before
)
if
expected
!=
r
.
shouldPull
{
t
.
Errorf
(
"Pull with Error %v: Expected %v found %v"
,
i
,
expected
,
r
.
shouldPull
)
}
}
}
func
createRepo
(
r
*
Repo
)
*
Repo
{
...
...
middleware/git/service.go
0 → 100644
View file @
6c6e0e3f
package
git
import
(
"sync"
"time"
)
// RepoService is the repository service that runs in background and
// periodic pull from the repository.
type
RepoService
struct
{
repo
*
Repo
running
bool
// whether service is running.
halt
chan
struct
{}
// channel to notify service to halt and stop pulling.
exit
chan
struct
{}
// channel to notify on exit.
}
// Start starts a new RepoService in background and adds it to monitor.
func
Start
(
repo
*
Repo
)
{
service
:=
&
RepoService
{
repo
,
true
,
make
(
chan
struct
{}),
make
(
chan
struct
{}),
}
// start service
go
func
(
s
*
RepoService
)
{
for
{
// if service is halted
if
!
s
.
running
{
// notify exit channel
service
.
exit
<-
struct
{}{}
break
}
time
.
Sleep
(
repo
.
Interval
)
err
:=
repo
.
Pull
()
if
err
!=
nil
{
logger
()
.
Println
(
err
)
}
}
}(
service
)
// add to monitor to enable halting
Monitor
.
add
(
service
)
}
// monitor monitors running services (RepoService)
// and can halt them.
type
monitor
struct
{
services
[]
*
RepoService
sync
.
Mutex
}
// add adds a new service to the monitor.
func
(
m
*
monitor
)
add
(
service
*
RepoService
)
{
m
.
Lock
()
defer
m
.
Unlock
()
m
.
services
=
append
(
m
.
services
,
service
)
// start a goroutine to listen for halt signal
service
.
running
=
true
go
func
(
r
*
RepoService
)
{
<-
r
.
halt
r
.
running
=
false
}(
service
)
}
// Stop stops at most `limit` currently running services that is pulling from git repo at
// repoURL. It returns list of exit channels for the services. A wait for message on the
// channels guarantees exit. If limit is less than zero, it is ignored.
// TODO find better ways to identify repos
func
(
m
*
monitor
)
Stop
(
repoURL
string
,
limit
int
)
[]
chan
struct
{}
{
m
.
Lock
()
defer
m
.
Unlock
()
var
chans
[]
chan
struct
{}
// locate services
for
i
,
j
:=
0
,
0
;
i
<
len
(
m
.
services
)
&&
((
limit
>=
0
&&
j
<
limit
)
||
limit
<
0
);
i
++
{
s
:=
m
.
services
[
i
]
if
s
.
repo
.
URL
==
repoURL
{
// send halt signal
s
.
halt
<-
struct
{}{}
chans
=
append
(
chans
,
s
.
exit
)
j
++
m
.
services
[
i
]
=
nil
}
}
// remove them from services list
services
:=
m
.
services
[
:
0
]
for
_
,
s
:=
range
m
.
services
{
if
s
!=
nil
{
services
=
append
(
services
,
s
)
}
}
m
.
services
=
services
return
chans
}
// StopAndWait is similar to stop but it waits for the services to terminate before
// returning.
func
(
m
*
monitor
)
StopAndWait
(
repoUrl
string
,
limit
int
)
{
chans
:=
m
.
Stop
(
repoUrl
,
limit
)
for
_
,
c
:=
range
chans
{
<-
c
}
}
middleware/git/service_test.go
0 → 100644
View file @
6c6e0e3f
package
git
import
(
"fmt"
"testing"
"time"
"github.com/mholt/caddy/middleware/git/gittest"
)
func
init
()
{
SetOS
(
gittest
.
FakeOS
)
}
func
Test
(
t
*
testing
.
T
)
{
repo
:=
&
Repo
{
URL
:
"git@github.com"
,
Interval
:
time
.
Second
}
Start
(
repo
)
if
len
(
Monitor
.
services
)
!=
1
{
t
.
Errorf
(
"Expected 1 service, found %v"
,
len
(
Monitor
.
services
))
}
Monitor
.
StopAndWait
(
repo
.
URL
,
1
)
if
len
(
Monitor
.
services
)
!=
0
{
t
.
Errorf
(
"Expected 1 service, found %v"
,
len
(
Monitor
.
services
))
}
repos
:=
make
([]
*
Repo
,
5
)
for
i
:=
0
;
i
<
5
;
i
++
{
repos
[
i
]
=
&
Repo
{
URL
:
fmt
.
Sprintf
(
"test%v"
,
i
),
Interval
:
time
.
Second
*
2
}
Start
(
repos
[
i
])
if
len
(
Monitor
.
services
)
!=
i
+
1
{
t
.
Errorf
(
"Expected %v service(s), found %v"
,
i
+
1
,
len
(
Monitor
.
services
))
}
}
time
.
Sleep
(
time
.
Second
*
5
)
Monitor
.
StopAndWait
(
repos
[
0
]
.
URL
,
1
)
if
len
(
Monitor
.
services
)
!=
4
{
t
.
Errorf
(
"Expected %v service(s), found %v"
,
4
,
len
(
Monitor
.
services
))
}
repo
=
&
Repo
{
URL
:
"git@github.com"
,
Interval
:
time
.
Second
}
Start
(
repo
)
if
len
(
Monitor
.
services
)
!=
5
{
t
.
Errorf
(
"Expected %v service(s), found %v"
,
5
,
len
(
Monitor
.
services
))
}
repo
=
&
Repo
{
URL
:
"git@github.com"
,
Interval
:
time
.
Second
*
2
}
Start
(
repo
)
if
len
(
Monitor
.
services
)
!=
6
{
t
.
Errorf
(
"Expected %v service(s), found %v"
,
6
,
len
(
Monitor
.
services
))
}
time
.
Sleep
(
time
.
Second
*
5
)
Monitor
.
StopAndWait
(
repo
.
URL
,
-
1
)
if
len
(
Monitor
.
services
)
!=
4
{
t
.
Errorf
(
"Expected %v service(s), found %v"
,
4
,
len
(
Monitor
.
services
))
}
}
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