Skip to content

Commit 35c91ef

Browse files
committed
Add tests for getCsharpHashPatterns
- Make the function more easily testable by allowing `makePatternCheck` to be stubbed. - Use `makePatternCheck` for base patterns as well.
1 parent 71abac7 commit 35c91ef

File tree

4 files changed

+147
-62
lines changed

4 files changed

+147
-62
lines changed

lib/analyze-action.js

Lines changed: 19 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/init-action.js

Lines changed: 21 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/dependency-caching.test.ts

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@ import * as fs from "fs";
22
import path from "path";
33

44
import test from "ava";
5-
6-
// import * as sinon from "sinon";
5+
import * as sinon from "sinon";
76

87
import { cacheKeyHashLength } from "./caching-utils";
98
import { createStubCodeQL } from "./codeql";
109
import {
1110
CacheConfig,
1211
checkHashPatterns,
12+
getCsharpHashPatterns,
1313
getFeaturePrefix,
1414
makePatternCheck,
15+
internal,
16+
CSHARP_BASE_PATTERNS,
17+
CSHARP_EXTRA_PATTERNS,
1518
} from "./dependency-caching";
1619
import { Feature } from "./feature-flags";
1720
import { KnownLanguage } from "./languages";
@@ -49,6 +52,70 @@ test("makePatternCheck - returns all patterns if any pattern matches", async (t)
4952
});
5053
});
5154

55+
test("getCsharpHashPatterns - returns base patterns if any pattern matches", async (t) => {
56+
const codeql = createStubCodeQL({});
57+
const features = createFeatures([]);
58+
const makePatternCheckStub = sinon.stub(internal, "makePatternCheck");
59+
60+
makePatternCheckStub
61+
.withArgs(CSHARP_BASE_PATTERNS)
62+
.resolves(CSHARP_BASE_PATTERNS);
63+
makePatternCheckStub.withArgs(CSHARP_EXTRA_PATTERNS).rejects();
64+
65+
await t.notThrowsAsync(async () => {
66+
const result = await getCsharpHashPatterns(codeql, features);
67+
t.deepEqual(result, CSHARP_BASE_PATTERNS);
68+
});
69+
});
70+
71+
test("getCsharpHashPatterns - returns base patterns if any base pattern matches and CsharpNewCacheKey is enabled", async (t) => {
72+
const codeql = createStubCodeQL({});
73+
const features = createFeatures([Feature.CsharpNewCacheKey]);
74+
const makePatternCheckStub = sinon.stub(internal, "makePatternCheck");
75+
76+
makePatternCheckStub
77+
.withArgs(CSHARP_BASE_PATTERNS)
78+
.resolves(CSHARP_BASE_PATTERNS);
79+
makePatternCheckStub
80+
.withArgs(CSHARP_EXTRA_PATTERNS)
81+
.resolves(CSHARP_EXTRA_PATTERNS);
82+
83+
await t.notThrowsAsync(async () => {
84+
const result = await getCsharpHashPatterns(codeql, features);
85+
t.deepEqual(result, CSHARP_BASE_PATTERNS);
86+
});
87+
});
88+
89+
test("getCsharpHashPatterns - returns extra patterns if any extra pattern matches and CsharpNewCacheKey is enabled", async (t) => {
90+
const codeql = createStubCodeQL({});
91+
const features = createFeatures([Feature.CsharpNewCacheKey]);
92+
const makePatternCheckStub = sinon.stub(internal, "makePatternCheck");
93+
94+
makePatternCheckStub.withArgs(CSHARP_BASE_PATTERNS).resolves(undefined);
95+
makePatternCheckStub
96+
.withArgs(CSHARP_EXTRA_PATTERNS)
97+
.resolves(CSHARP_EXTRA_PATTERNS);
98+
99+
await t.notThrowsAsync(async () => {
100+
const result = await getCsharpHashPatterns(codeql, features);
101+
t.deepEqual(result, CSHARP_EXTRA_PATTERNS);
102+
});
103+
});
104+
105+
test("getCsharpHashPatterns - returns undefined if neither base nor extra patterns match", async (t) => {
106+
const codeql = createStubCodeQL({});
107+
const features = createFeatures([Feature.CsharpNewCacheKey]);
108+
const makePatternCheckStub = sinon.stub(internal, "makePatternCheck");
109+
110+
makePatternCheckStub.withArgs(CSHARP_BASE_PATTERNS).resolves(undefined);
111+
makePatternCheckStub.withArgs(CSHARP_EXTRA_PATTERNS).resolves(undefined);
112+
113+
await t.notThrowsAsync(async () => {
114+
const result = await getCsharpHashPatterns(codeql, features);
115+
t.deepEqual(result, undefined);
116+
});
117+
});
118+
52119
test("checkHashPatterns - logs when no patterns match", async (t) => {
53120
const codeql = createStubCodeQL({});
54121
const features = createFeatures([]);

src/dependency-caching.ts

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -85,49 +85,55 @@ export async function makePatternCheck(
8585
return patterns;
8686
}
8787

88+
/** These files contain accurate information about dependencies, including the exact versions
89+
* that the relevant package manager has determined for the project. Using these gives us
90+
* stable hashes unless the dependencies change.
91+
*/
92+
export const CSHARP_BASE_PATTERNS = [
93+
// NuGet
94+
"**/packages.lock.json",
95+
// Paket
96+
"**/paket.lock",
97+
];
98+
99+
/** These are less accurate for use in cache key calculations, because they:
100+
*
101+
* - Don't contain the exact versions used. They may only contain version ranges or none at all.
102+
* - They contain information unrelated to dependencies, which we don't care about.
103+
*
104+
* As a result, the hash we compute from these files may change, even if
105+
* the dependencies haven't changed.
106+
*/
107+
export const CSHARP_EXTRA_PATTERNS = [
108+
"**/*.csproj",
109+
"**/packages.config",
110+
"**/nuget.config",
111+
];
112+
88113
/**
89114
* Returns the list of glob patterns that should be used to calculate the cache key hash
90-
* for a C# dependency cache.
115+
* for a C# dependency cache. This will try to use `CSHARP_BASE_PATTERNS` whenever possible.
116+
* As a fallback, it will also use `CSHARP_EXTRA_PATTERNS` if the corresponding FF is enabled.
91117
*
92118
* @param codeql The CodeQL instance to use.
93119
* @param features Information about which FFs are enabled.
94120
* @returns A list of glob patterns to use for hashing.
95121
*/
96-
async function getCsharpHashPatterns(
122+
export async function getCsharpHashPatterns(
97123
codeql: CodeQL,
98124
features: FeatureEnablement,
99125
): Promise<string[] | undefined> {
100-
// These files contain accurate information about dependencies, including the exact versions
101-
// that the relevant package manager has determined for the project. Using these gives us
102-
// stable hashes unless the dependencies change.
103-
const basePatterns = [
104-
// NuGet
105-
"**/packages.lock.json",
106-
// Paket
107-
"**/paket.lock",
108-
];
109-
const globber = await makeGlobber(basePatterns);
126+
const basePatterns = await internal.makePatternCheck(CSHARP_BASE_PATTERNS);
110127

111-
if ((await globber.glob()).length > 0) {
128+
if (basePatterns !== undefined) {
112129
return basePatterns;
113130
}
114131

115132
if (await features.getValue(Feature.CsharpNewCacheKey, codeql)) {
116-
// These are less accurate for use in cache key calculations, because they:
117-
//
118-
// - Don't contain the exact versions used. They may only contain version ranges or none at all.
119-
// - They contain information unrelated to dependencies, which we don't care about.
120-
//
121-
// As a result, the hash we compute from these files may change, even if
122-
// the dependencies haven't changed.
123-
return makePatternCheck([
124-
"**/*.csproj",
125-
"**/packages.config",
126-
"**/nuget.config",
127-
]);
133+
return internal.makePatternCheck(CSHARP_EXTRA_PATTERNS);
128134
}
129135

130-
// If we get to this point, the `basePatterns` didn't find any files,
136+
// If we get to this point, we didn't find any files with `CSHARP_BASE_PATTERNS`,
131137
// and `Feature.CsharpNewCacheKey` is not enabled.
132138
return undefined;
133139
}
@@ -139,7 +145,7 @@ const defaultCacheConfigs: { [language: string]: CacheConfig } = {
139145
java: {
140146
getDependencyPaths: getJavaDependencyDirs,
141147
getHashPatterns: async () =>
142-
makePatternCheck([
148+
internal.makePatternCheck([
143149
// Maven
144150
"**/pom.xml",
145151
// Gradle
@@ -157,7 +163,7 @@ const defaultCacheConfigs: { [language: string]: CacheConfig } = {
157163
},
158164
go: {
159165
getDependencyPaths: () => [join(os.homedir(), "go", "pkg", "mod")],
160-
getHashPatterns: async () => makePatternCheck(["**/go.sum"]),
166+
getHashPatterns: async () => internal.makePatternCheck(["**/go.sum"]),
161167
},
162168
};
163169

@@ -547,3 +553,7 @@ export async function getDependencyCacheUsage(
547553

548554
return undefined;
549555
}
556+
557+
export const internal = {
558+
makePatternCheck,
559+
};

0 commit comments

Comments
 (0)