Skip to content
This repository was archived by the owner on Apr 13, 2020. It is now read-only.

Commit 9a7a5d2

Browse files
Patching for infra scaffold caching, PAT handling and macOS (#246)
* adding failsafe on download * modifying pipe * modifying pipe download task * modifying pipe download task syntax * final syntax test * explicit conditionals for download * more syntax mods * debugging for Yvonne PR status * redacted * redacted * updates * working int-test with generate yaml * add validation for pr * adding fix for private repo cloning in yml * debugging * adding refernce for infra yml * removing debug statemnets * discovery --> fabrikam * modifying infra repo name * removing debug lines * yvonne changes * Adding retry logic, fixing macos, consolidating pipeline file * debugging for pipeline * path debug * fixing in pipeline * removing pipeline debug statements * adjusting path * adjusting path for pipeline yaml * final commit for copy pipeline path * updating readme * pulling master * refactoring to decoupled methods for git * improving code coverage * await added * clean up on comments * unit tests for retry * updating for unit tests * modifying for unit tests Co-authored-by: Yvonne Radsmikham <yvonne.radsmikham@gmail.com>
1 parent 745598b commit 9a7a5d2

File tree

6 files changed

+258
-65
lines changed

6 files changed

+258
-65
lines changed

azure-pipelines/templates/infra-generation-pipeline.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,4 @@ steps:
140140
fi
141141
env:
142142
ACCESS_TOKEN_SECRET: $(ACCESS_TOKEN_SECRET)
143-
displayName: 'Commit and Push to Generated Repository'
143+
displayName: 'Commit and Push to Generated Repository'

src/commands/infra/generate.test.ts

Lines changed: 155 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import fs from "fs";
2+
import * as fsExtra from "fs-extra";
23
import path from "path";
4+
import simpleGit from "simple-git/promise";
35
import { loadConfigurationFromLocalEnv, readYaml } from "../../config";
46
import { safeGitUrlForLogging } from "../../lib/gitutils";
57
import { removeDir } from "../../lib/ioUtil";
@@ -19,7 +21,9 @@ import {
1921
generateConfig,
2022
generateTfvars,
2123
gitCheckout,
24+
gitClone,
2225
gitFetchPull,
26+
retryRemoteValidate,
2327
validateDefinition,
2428
validateRemoteSource,
2529
validateTemplateSources
@@ -76,27 +80,16 @@ describe("fetch execute function", () => {
7680
expect(exitFn.mock.calls).toEqual([[1]]);
7781
});
7882
it("with project value", async () => {
79-
const validateDefinitionMock = jest.spyOn(generate, "validateDefinition");
80-
validateDefinitionMock.mockImplementation(
81-
() => DefinitionYAMLExistence.BOTH_EXIST
82-
);
83-
84-
const validateRemoteSourceMock = jest.spyOn(
85-
generate,
86-
"validateRemoteSource"
87-
);
88-
validateRemoteSourceMock.mockImplementation(() => Promise.resolve());
89-
90-
const validateTemplateSourcesMock = jest.spyOn(
91-
generate,
92-
"validateTemplateSources"
93-
);
94-
validateTemplateSourcesMock.mockImplementation(() => {
95-
return {};
96-
});
97-
98-
const generateConfigMock = jest.spyOn(generate, "generateConfig");
99-
generateConfigMock.mockImplementation(async () => Promise.resolve());
83+
jest
84+
.spyOn(generate, "validateDefinition")
85+
.mockReturnValueOnce(DefinitionYAMLExistence.BOTH_EXIST);
86+
jest
87+
.spyOn(generate, "validateRemoteSource")
88+
.mockReturnValueOnce(Promise.resolve());
89+
jest.spyOn(generate, "validateTemplateSources").mockReturnValueOnce({});
90+
jest
91+
.spyOn(generate, "generateConfig")
92+
.mockReturnValueOnce(Promise.resolve());
10093

10194
const exitFn = jest.fn();
10295
await execute(
@@ -112,6 +105,120 @@ describe("fetch execute function", () => {
112105
});
113106
});
114107

108+
describe("test validateRemoteSource function", () => {
109+
it("positive test", async () => {
110+
jest
111+
.spyOn(infraCommon, "repoCloneRegex")
112+
.mockReturnValueOnce(Promise.resolve("sourceFolder"));
113+
jest
114+
.spyOn(generate, "checkRemoteGitExist")
115+
.mockReturnValueOnce(Promise.resolve());
116+
jest.spyOn(generate, "gitClone").mockReturnValueOnce(Promise.resolve());
117+
jest.spyOn(generate, "gitCheckout").mockReturnValueOnce(Promise.resolve());
118+
119+
await validateRemoteSource({
120+
source: "source",
121+
version: "0.1"
122+
});
123+
});
124+
it("positive test: with Error refusing to merge unrelated histories", async () => {
125+
jest
126+
.spyOn(infraCommon, "repoCloneRegex")
127+
.mockReturnValueOnce(Promise.resolve("sourceFolder"));
128+
jest
129+
.spyOn(generate, "checkRemoteGitExist")
130+
.mockReturnValueOnce(Promise.resolve());
131+
jest
132+
.spyOn(generate, "gitClone")
133+
.mockReturnValueOnce(
134+
Promise.reject(new Error("refusing to merge unrelated histories"))
135+
);
136+
jest
137+
.spyOn(generate, "retryRemoteValidate")
138+
.mockReturnValueOnce(Promise.resolve());
139+
140+
await validateRemoteSource({
141+
source: "source",
142+
version: "0.1"
143+
});
144+
});
145+
it("positive test: with Error Authentication failed", async () => {
146+
jest
147+
.spyOn(infraCommon, "repoCloneRegex")
148+
.mockReturnValueOnce(Promise.resolve("sourceFolder"));
149+
jest
150+
.spyOn(generate, "checkRemoteGitExist")
151+
.mockReturnValueOnce(Promise.resolve());
152+
jest
153+
.spyOn(generate, "gitClone")
154+
.mockReturnValueOnce(Promise.reject(new Error("Authentication failed")));
155+
jest
156+
.spyOn(generate, "retryRemoteValidate")
157+
.mockReturnValueOnce(Promise.resolve());
158+
159+
await validateRemoteSource({
160+
source: "source",
161+
version: "0.1"
162+
});
163+
});
164+
it("negative test: with unknown Error", async () => {
165+
jest
166+
.spyOn(infraCommon, "repoCloneRegex")
167+
.mockReturnValueOnce(Promise.resolve("sourceFolder"));
168+
jest
169+
.spyOn(generate, "checkRemoteGitExist")
170+
.mockReturnValueOnce(Promise.resolve());
171+
jest
172+
.spyOn(generate, "gitClone")
173+
.mockReturnValueOnce(Promise.reject(new Error("other error")));
174+
jest
175+
.spyOn(generate, "retryRemoteValidate")
176+
.mockReturnValueOnce(Promise.resolve());
177+
178+
try {
179+
await validateRemoteSource({
180+
source: "source",
181+
version: "0.1"
182+
});
183+
expect(true).toBe(false);
184+
} catch (err) {
185+
expect(err.message).toBe(
186+
"Failure error thrown during retry Error: Unable to determine error from supported retry cases other error"
187+
);
188+
}
189+
});
190+
});
191+
192+
describe("test retryRemoteValidate function", () => {
193+
it("positive test", async () => {
194+
jest.spyOn(fsExtra, "removeSync").mockReturnValueOnce();
195+
jest.spyOn(generate, "createGenerated").mockReturnValue();
196+
jest.spyOn(generate, "gitClone").mockReturnValueOnce(Promise.resolve());
197+
jest.spyOn(generate, "gitFetchPull").mockReturnValueOnce(Promise.resolve());
198+
jest.spyOn(generate, "gitCheckout").mockReturnValueOnce(Promise.resolve());
199+
await retryRemoteValidate("source", "sourcePath", "safeLoggingUrl", "0.1");
200+
});
201+
it("negative test", async () => {
202+
jest.spyOn(fsExtra, "removeSync").mockReturnValueOnce();
203+
jest.spyOn(generate, "createGenerated").mockReturnValue();
204+
jest
205+
.spyOn(generate, "gitClone")
206+
.mockReturnValueOnce(Promise.reject(new Error("error")));
207+
208+
try {
209+
await retryRemoteValidate(
210+
"source",
211+
"sourcePath",
212+
"safeLoggingUrl",
213+
"0.1"
214+
);
215+
expect(true).toBe(false);
216+
} catch (err) {
217+
expect(err).toBeDefined();
218+
}
219+
});
220+
});
221+
115222
describe("test generateTfvars function", () => {
116223
it("undefined as data", () => {
117224
expect(generateTfvars(undefined)).toEqual([]);
@@ -463,19 +570,38 @@ describe("test gitCheckout function", () => {
463570
});
464571
});
465572

573+
describe("test gitClone function", () => {
574+
it("postive Test", async () => {
575+
const git = simpleGit();
576+
git.clone = async () => {
577+
return "ok";
578+
};
579+
await gitClone(git, "source", "path");
580+
// no exception thrown
581+
});
582+
it("negative Test", async () => {
583+
const git = simpleGit();
584+
git.clone = async () => {
585+
throw new Error("Error");
586+
};
587+
try {
588+
await gitClone(git, "source", "path");
589+
expect(true).toBe(false);
590+
} catch (e) {
591+
expect(e.message).toBe("Error");
592+
}
593+
});
594+
});
595+
466596
describe("Validate remote git source", () => {
467597
test("Validating that a git source is cloned to .spk/templates", async () => {
468598
jest
469599
.spyOn(generate, "checkRemoteGitExist")
470600
.mockImplementationOnce(async () => {
471601
return;
472602
});
473-
jest.spyOn(generate, "gitFetchPull").mockImplementationOnce(async () => {
474-
return;
475-
});
476-
jest.spyOn(generate, "gitCheckout").mockImplementationOnce(async () => {
477-
return;
478-
});
603+
jest.spyOn(generate, "gitFetchPull").mockReturnValueOnce(Promise.resolve());
604+
jest.spyOn(generate, "gitCheckout").mockReturnValueOnce(Promise.resolve());
479605

480606
const mockParentPath = "src/commands/infra/mocks/discovery-service";
481607
const mockProjectPath = "src/commands/infra/mocks/discovery-service/west";
@@ -497,23 +623,8 @@ describe("Validate remote git source", () => {
497623
});
498624
});
499625

500-
jest.spyOn(generate, "gitClone").mockImplementation(
501-
(source: string, sourcePath: string): Promise<void> => {
502-
logger.info(`gitClone function mocked.`);
503-
return new Promise(resolve => {
504-
resolve();
505-
});
506-
}
507-
);
508-
509-
jest.spyOn(generate, "createGenerated").mockImplementation(
510-
(projectPath: string): Promise<string> => {
511-
logger.info(`createGenerated function mocked.`);
512-
return new Promise(resolve => {
513-
resolve();
514-
});
515-
}
516-
);
626+
jest.spyOn(generate, "gitClone").mockReturnValue(Promise.resolve());
627+
jest.spyOn(generate, "createGenerated").mockReturnValue();
517628

518629
jest.spyOn(generate, "checkTfvars").mockImplementation(
519630
(generatedPath: string, tfvarsFilename: string): Promise<void> => {

0 commit comments

Comments
 (0)