-
Notifications
You must be signed in to change notification settings - Fork 964
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
App Hosting Emulator Prototype (#7505)
- Loading branch information
Showing
11 changed files
with
173 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { EmulatorLogger } from "../emulatorLogger"; | ||
import { EmulatorInfo, EmulatorInstance, Emulators } from "../types"; | ||
import { start as apphostingStart } from "./serve"; | ||
interface AppHostingEmulatorArgs { | ||
options?: any; | ||
port?: number; | ||
host?: string; | ||
} | ||
|
||
/** | ||
* An emulator instance for Firebase's App Hosting product. This class provides a simulated | ||
* environment for testing App Hosting features locally. | ||
*/ | ||
export class AppHostingEmulator implements EmulatorInstance { | ||
private logger = EmulatorLogger.forEmulator(Emulators.APPHOSTING); | ||
constructor(private args: AppHostingEmulatorArgs) {} | ||
|
||
async start(): Promise<void> { | ||
this.args.options.host = this.args.host; | ||
this.args.options.port = this.args.port; | ||
|
||
this.logger.logLabeled("INFO", Emulators.APPHOSTING, "starting apphosting emulator"); | ||
const { port } = await apphostingStart(this.args.options); | ||
this.logger.logLabeled("INFO", Emulators.APPHOSTING, `serving on port ${port}`); | ||
} | ||
|
||
connect(): Promise<void> { | ||
this.logger.logLabeled("INFO", Emulators.APPHOSTING, "connecting apphosting emulator"); | ||
return Promise.resolve(); | ||
} | ||
|
||
stop(): Promise<void> { | ||
this.logger.logLabeled("INFO", Emulators.APPHOSTING, "stopping apphosting emulator"); | ||
return Promise.resolve(); | ||
} | ||
|
||
getInfo(): EmulatorInfo { | ||
return { | ||
name: Emulators.APPHOSTING, | ||
host: this.args.host!, | ||
port: this.args.port!, | ||
}; | ||
} | ||
|
||
getName(): Emulators { | ||
return Emulators.APPHOSTING; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import * as portUtils from "../portUtils"; | ||
import * as sinon from "sinon"; | ||
import * as spawn from "../../init/spawn"; | ||
import { expect } from "chai"; | ||
import * as serve from "./serve"; | ||
|
||
describe("serve", () => { | ||
let checkListenableStub: sinon.SinonStub; | ||
let wrapSpawnStub: sinon.SinonStub; | ||
|
||
beforeEach(() => { | ||
checkListenableStub = sinon.stub(portUtils, "checkListenable"); | ||
wrapSpawnStub = sinon.stub(spawn, "wrapSpawn"); | ||
}); | ||
|
||
afterEach(() => { | ||
checkListenableStub.restore(); | ||
wrapSpawnStub.restore(); | ||
}); | ||
|
||
describe("start", () => { | ||
it("should only select an available port to serve", async () => { | ||
checkListenableStub.onFirstCall().returns(false); | ||
checkListenableStub.onSecondCall().returns(false); | ||
checkListenableStub.onThirdCall().returns(true); | ||
|
||
wrapSpawnStub.returns(Promise.resolve()); | ||
|
||
const res = await serve.start({ host: "127.0.0.1", port: 5000 }); | ||
expect(res.port).to.equal(5002); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/** | ||
* Start the App Hosting server. | ||
* @param options the Firebase CLI options. | ||
*/ | ||
import { isIPv4 } from "net"; | ||
import { checkListenable } from "../portUtils"; | ||
import { wrapSpawn } from "../../init/spawn"; | ||
|
||
/** | ||
* Spins up a project locally by running the project's dev command. | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
export async function start(options: any): Promise<{ port: number }> { | ||
let port = options.port; | ||
while (!(await availablePort(options.host, port))) { | ||
port += 1; | ||
} | ||
|
||
serve(options, port); | ||
|
||
return { port }; | ||
} | ||
|
||
function availablePort(host: string, port: number): Promise<boolean> { | ||
return checkListenable({ | ||
address: host, | ||
port, | ||
family: isIPv4(host) ? "IPv4" : "IPv6", | ||
}); | ||
} | ||
|
||
/** | ||
* Exported for unit testing | ||
*/ | ||
export async function serve(options: any, port: string) { | ||
// TODO: update to support other package managers and frameworks other than NextJS | ||
await wrapSpawn("npm", ["run", "dev", "--", "-H", options.host, "-p", port], process.cwd()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters