Skip to content

Commit 5085166

Browse files
authored
wip: update tests and fix unhashable initial commit (#25)
* fix: add hashing of initial commit * wip: updated tests according to previous change of commit hasher * wip: test refactor * chore: remove unused configurator from CodeLongevity
1 parent c904f86 commit 5085166

File tree

5 files changed

+72
-47
lines changed

5 files changed

+72
-47
lines changed

build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ dependencies {
6363
compile 'com.github.kittinunf.fuel:fuel-rxjava:1.9.0'
6464
compile group: 'org.eclipse.jgit', name: 'org.eclipse.jgit',
6565
version: '4.8.0.201706111038-r'
66+
6667
testCompile 'org.jetbrains.kotlin:kotlin-test'
6768
testCompile 'org.jetbrains.spek:spek-api:1.1.2'
6869
testCompile 'org.junit.platform:junit-platform-runner:1.0.0-M4'
@@ -76,7 +77,7 @@ protobuf {
7677
}
7778

7879
sourceSets.main.java.srcDirs += 'build/generated/source/proto/main/java'
79-
sourceSets.test.java.srcDirs += 'src/test'
80+
sourceSets.test.java.srcDirs += 'src/test/kotlin'
8081
compileKotlin.dependsOn ':generateProto'
8182

8283
// Include dependent libraries in archive.

src/main/kotlin/app/hashers/CodeLongevity.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ class CodeLine(val from: RevCommitLine, val to: RevCommitLine,
7979
class CodeLongevity(private val localRepo: LocalRepo,
8080
private val serverRepo: Repo,
8181
private val api: Api,
82-
private val configurator: Configurator,
8382
private val git: Git, tailRev: String = "") {
8483
val CODE_LONGEVITY_KEY = "line-longevity-avg"
8584
val CODE_LONGEVITY_REPO_KEY = "line-longevity-repo-avg"

src/main/kotlin/app/hashers/CommitHasher.kt

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import java.nio.charset.Charset
2323
import org.eclipse.jgit.diff.DiffFormatter
2424
import org.eclipse.jgit.lib.ObjectId
2525
import org.eclipse.jgit.errors.MissingObjectException
26+
import org.eclipse.jgit.revwalk.RevCommit
2627
import org.eclipse.jgit.util.io.DisabledOutputStream
2728
import java.util.concurrent.TimeUnit
2829

@@ -32,7 +33,6 @@ import java.util.concurrent.TimeUnit
3233
class CommitHasher(private val localRepo: LocalRepo,
3334
private val repo: Repo = Repo(),
3435
private val api: Api,
35-
private val configurator: Configurator,
3636
private val git: Git) {
3737
private val gitRepo: Repository = git.repository
3838

@@ -46,7 +46,9 @@ class CommitHasher(private val localRepo: LocalRepo,
4646
private fun hashAndSendCommits() {
4747
val lastKnownCommit = repo.commits.lastOrNull()
4848
val knownCommits = repo.commits.toHashSet()
49-
getObservableCommits()
49+
// Commits are combined in pairs, an empty commit concatenated to
50+
// calculate the diff of the initial commit.
51+
Observable.concat(getObservableCommits(), Observable.just(Commit()))
5052
.pairWithNext() // Pair commits to get diff.
5153
.takeWhile { (new, _) -> // Hash until last known commit.
5254
new.rehash != lastKnownCommit?.rehash }
@@ -77,15 +79,12 @@ class CommitHasher(private val localRepo: LocalRepo,
7779
private fun getDiffFiles(commitNew: Commit,
7880
commitOld: Commit): List<DiffFile> {
7981
// TODO(anatoly): Binary files.
80-
val revCommitNew = commitNew.raw
81-
val revCommitOld = commitOld.raw
82-
if (revCommitNew == null || revCommitOld == null) {
83-
return listOf()
84-
}
82+
val revCommitNew:RevCommit? = commitNew.raw
83+
val revCommitOld:RevCommit? = commitOld.raw
8584

8685
return DiffFormatter(DisabledOutputStream.INSTANCE).use { formatter ->
8786
formatter.setRepository(gitRepo)
88-
formatter.scan(revCommitOld.tree, revCommitNew.tree)
87+
formatter.scan(revCommitOld?.tree, revCommitNew?.tree)
8988
// RENAME change type doesn't change file content.
9089
.filter { it.changeType != DiffEntry.ChangeType.RENAME }
9190
.map { diff ->
@@ -112,7 +111,7 @@ class CommitHasher(private val localRepo: LocalRepo,
112111
gitRepo.open(objectId).bytes.toString(Charset.defaultCharset())
113112
.split('\n')
114113
} catch (e: MissingObjectException) {
115-
listOf<String>()
114+
listOf()
116115
}
117116
}
118117

@@ -154,11 +153,11 @@ class CommitHasher(private val localRepo: LocalRepo,
154153

155154
fun <T> Observable<T>.pairWithNext(): Observable<Pair<T, T>> {
156155
return this.map { emit -> Pair(emit, emit) }
157-
// Accumulate emits by prev-next pair.
158-
.scan { pairAccumulated, pairNext ->
159-
Pair(pairAccumulated.second, pairNext.second)
160-
}
161-
.skip(1) // Skip initial not paired emit.
156+
// Accumulate emits by prev-next pair.
157+
.scan { pairAccumulated, pairNext ->
158+
Pair(pairAccumulated.second, pairNext.second)
159+
}
160+
.skip(1) // Skip initial not paired emit.
162161
}
163162

164163
fun update() {

src/main/kotlin/app/hashers/RepoHasher.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ class RepoHasher(private val localRepo: LocalRepo, private val api: Api,
3838
getRepoFromServer()
3939

4040
// Hash by all plugins.
41-
CommitHasher(localRepo, repo, api, configurator, git).update()
42-
CodeLongevity(localRepo, repo, api, configurator, git).update()
41+
CommitHasher(localRepo, repo, api, git).update()
42+
CodeLongevity(localRepo, repo, api, git).update()
4343

4444
// Confirm hashing completion.
4545
postRepoToServer()

src/test/CommitUploadProtocolTest.kt renamed to src/test/kotlin/app/CommitHasherTest.kt

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,52 @@
11
// Copyright 2017 Sourcerer Inc. All Rights Reserved.
22
// Author: Liubov Yaronskaya ([email protected])
3+
// Author: Anatoly Kislov ([email protected])
34

4-
package test
5+
package app
56

6-
import app.hashers.CommitHasher
77
import app.api.MockApi
8-
import app.config.MockConfigurator
8+
import app.hashers.CommitHasher
99
import app.model.*
1010
import app.utils.RepoHelper
1111
import org.eclipse.jgit.api.Git
1212
import org.jetbrains.spek.api.Spek
13-
import org.jetbrains.spek.api.dsl.*
13+
import org.jetbrains.spek.api.dsl.given
14+
import org.jetbrains.spek.api.dsl.it
1415
import java.io.File
1516
import java.util.stream.StreamSupport.stream
1617
import kotlin.streams.toList
1718
import kotlin.test.assertEquals
1819
import kotlin.test.assertNotEquals
1920

20-
class CommitUploadProtocolTest : Spek({
21+
class CommitHasherTest : Spek({
22+
val userName = "Contributor"
23+
val userEmail = "[email protected]"
24+
25+
// Creation of test repo.
2126
val repoPath = "./tmp_repo/.git"
2227
val git = Git.init().setGitDir(File(repoPath)).call()
28+
val config = git.repository.config
29+
config.setString("user", null, "name", userName)
30+
config.setString("user", null, "email", userEmail)
31+
config.save()
32+
33+
// Common parameters for CommitHasher.
2334
val gitHasher = Git.open(File(repoPath))
24-
val localRepo: LocalRepo = LocalRepo(repoPath)
25-
val initialCommit = Commit(git.commit().setMessage("Initial commit.").call())
26-
val repoRehash = RepoHelper.calculateRepoRehash(initialCommit.rehash, localRepo)
27-
var repo = Repo(rehash = repoRehash, initialCommitRehash = initialCommit.rehash)
28-
repo.commits = listOf(initialCommit)
35+
val localRepo = LocalRepo(repoPath)
36+
localRepo.author = Author(userName, userEmail)
37+
val initialCommit = Commit(git.commit().setMessage("Initial commit").call())
38+
val repoRehash = RepoHelper.calculateRepoRehash(initialCommit.rehash,
39+
localRepo)
40+
val repo = Repo(rehash = repoRehash,
41+
initialCommitRehash = initialCommit.rehash)
2942

3043
fun getRepoRehash(git: Git, localRepo: LocalRepo): String {
3144

3245
val initialRevCommit = stream(git.log().call().spliterator(), false)
3346
.toList().first()
3447
val initialCommit = Commit(initialRevCommit)
3548
val repoRehash = RepoHelper.calculateRepoRehash(initialCommit.rehash,
36-
localRepo)
49+
localRepo)
3750
return repoRehash
3851
}
3952

@@ -43,12 +56,26 @@ class CommitUploadProtocolTest : Spek({
4356
return lastCommit
4457
}
4558

46-
given("empty repo") {
59+
given("repo with initial commit and no history") {
60+
repo.commits = listOf()
61+
62+
val mockApi = MockApi(mockRepo = repo)
63+
CommitHasher(localRepo, repo, mockApi, gitHasher).update()
64+
65+
it("send added commits") {
66+
assertEquals(1, mockApi.receivedAddedCommits.size)
67+
}
68+
69+
it("doesn't send deleted commits") {
70+
assertEquals(0, mockApi.receivedDeletedCommits.size)
71+
}
72+
}
73+
74+
given("repo with initial commit") {
4775
repo.commits = listOf(getLastCommit(git))
4876

4977
val mockApi = MockApi(mockRepo = repo)
50-
val mockConfigurator = MockConfigurator(mockRepos = mutableListOf(repo))
51-
CommitHasher(localRepo, repo, mockApi, mockConfigurator, gitHasher).update()
78+
CommitHasher(localRepo, repo, mockApi, gitHasher).update()
5279

5380
it("doesn't send added commits") {
5481
assertEquals(0, mockApi.receivedAddedCommits.size)
@@ -61,12 +88,12 @@ class CommitUploadProtocolTest : Spek({
6188

6289
given("happy path: added one commit") {
6390
repo.commits = listOf(getLastCommit(git))
91+
6492
val mockApi = MockApi(mockRepo = repo)
65-
val mockConfigurator = MockConfigurator(mockRepos = mutableListOf(repo))
6693

6794
val revCommit = git.commit().setMessage("Second commit.").call()
6895
val addedCommit = Commit(revCommit)
69-
CommitHasher(localRepo, repo, mockApi, mockConfigurator, gitHasher).update()
96+
CommitHasher(localRepo, repo, mockApi, gitHasher).update()
7097

7198
it("doesn't send deleted commits") {
7299
assertEquals(0, mockApi.receivedDeletedCommits.size)
@@ -83,21 +110,24 @@ class CommitUploadProtocolTest : Spek({
83110

84111
given("happy path: added a few new commits") {
85112
repo.commits = listOf(getLastCommit(git))
113+
86114
val mockApi = MockApi(mockRepo = repo)
87-
val mockConfigurator = MockConfigurator(mockRepos = mutableListOf(repo))
88115

89116
val otherAuthorsNames = listOf("a", "b", "a")
90117
val otherAuthorsEmails = listOf("a@a", "b@b", "a@a")
91118
for (i in 0..2) {
92-
git.commit().setMessage("Create $i.").setAuthor(otherAuthorsNames.get(i), otherAuthorsEmails.get(i)).call()
119+
git.commit().setMessage("Create $i.")
120+
.setAuthor(otherAuthorsNames.get(i),
121+
otherAuthorsEmails.get(i))
122+
.call()
93123
}
94124
val authorCommits = mutableListOf<Commit>()
95125
for (i in 0..4) {
96126
val message = "Created $i by author."
97127
val revCommit = git.commit().setMessage(message).call()
98128
authorCommits.add(Commit(revCommit))
99129
}
100-
CommitHasher(localRepo, repo, mockApi, mockConfigurator, gitHasher).update()
130+
CommitHasher(localRepo, repo, mockApi, gitHasher).update()
101131

102132
it("posts five commits as added") {
103133
assertEquals(5, mockApi.receivedAddedCommits.size)
@@ -108,12 +138,12 @@ class CommitUploadProtocolTest : Spek({
108138
}
109139

110140
it("processes author's commits") {
111-
assertEquals(authorCommits.asReversed(), mockApi.receivedAddedCommits)
141+
assertEquals(authorCommits.asReversed(),
142+
mockApi.receivedAddedCommits)
112143
}
113144
}
114145

115146
given("fork event") {
116-
117147
val forkedRepoPath = "./forked_repo/"
118148
val originalRepoPath = "./original_repo/"
119149
val forked = Git.cloneRepository()
@@ -138,13 +168,12 @@ class CommitUploadProtocolTest : Spek({
138168
forked.close()
139169
original.repository.close()
140170
original.close()
141-
142171
}
143172

144173
given("lost server") {
145174
repo.commits = listOf(getLastCommit(git))
146-
var mockApi = MockApi(mockRepo = repo)
147-
var mockConfigurator = MockConfigurator(mockRepos = mutableListOf(repo))
175+
176+
val mockApi = MockApi(mockRepo = repo)
148177

149178
// Add some commits.
150179
val addedCommits = mutableListOf<Commit>()
@@ -153,14 +182,12 @@ class CommitUploadProtocolTest : Spek({
153182
val revCommit = git.commit().setMessage(message).call()
154183
addedCommits.add(Commit(revCommit))
155184
}
156-
CommitHasher(localRepo, repo, mockApi, mockConfigurator, gitHasher).update()
157185

158186
// Remove one commit from server history.
159187
val removedCommit = addedCommits.removeAt(1)
160188
repo.commits = addedCommits.toList().asReversed()
161-
mockConfigurator = MockConfigurator(mockRepos = mutableListOf(repo))
162-
mockApi = MockApi(mockRepo = repo)
163-
CommitHasher(localRepo, repo, mockApi, mockConfigurator, gitHasher).update()
189+
190+
CommitHasher(localRepo, repo, mockApi, gitHasher).update()
164191

165192
it("adds posts one commit as added and received commit is lost one") {
166193
assertEquals(1, mockApi.receivedAddedCommits.size)
@@ -170,7 +197,6 @@ class CommitUploadProtocolTest : Spek({
170197
it("doesn't posts deleted commits") {
171198
assertEquals(0, mockApi.receivedDeletedCommits.size)
172199
}
173-
174200
}
175201

176202
Runtime.getRuntime().exec("src/test/delete_repo.sh").waitFor()

0 commit comments

Comments
 (0)