66package main
77
88import (
9+ "os"
10+ "path/filepath"
911 "testing"
1012 "github.com/stretchr/testify/assert"
1113)
@@ -25,7 +27,7 @@ func Test_ExamplePythonStartupScriptGenerator_buildGunicornCommandForModule_only
2527 assert .Equal (t , expected , actual )
2628}
2729
28- func ExamplePythonStartupScriptGenerator_buildGunicornCommandForModule_moduleAndPath (t * testing.T ) {
30+ func Test_buildGunicornCommandForModule_moduleAndPath (t * testing.T ) {
2931 // Arrange
3032 expected := "GUNICORN_CMD_ARGS=\" --timeout 600 --access-logfile '-' --error-logfile '-'" +
3133 " --chdir=/a/b/c\" gunicorn module.py"
@@ -40,7 +42,104 @@ func ExamplePythonStartupScriptGenerator_buildGunicornCommandForModule_moduleAnd
4042 assert .Equal (t , expected , actual )
4143}
4244
43- func ExamplePythonStartupScriptGenerator_buildGunicornCommandForModule_moduleAndPathAndHost (t * testing.T ) {
45+ // FastAPI: gunicorn command with uvicorn worker class
46+ func Test_buildGunicornCommandForModule_FastAPI_withUvicornWorker (t * testing.T ) {
47+ // Arrange
48+ expected := "GUNICORN_CMD_ARGS=\" --timeout 600 --access-logfile '-' --error-logfile '-'" +
49+ " --bind=0.0.0.0:80 --chdir=/home/site/wwwroot\" gunicorn " +
50+ "-k uvicorn_worker.UvicornWorker main:app"
51+ gen := PythonStartupScriptGenerator {
52+ BindPort : "80" ,
53+ }
54+
55+ // Act
56+ actual := gen .buildGunicornCommandForModule (
57+ "-k uvicorn_worker.UvicornWorker main:app" , "/home/site/wwwroot" )
58+
59+ // Assert
60+ assert .Equal (t , expected , actual )
61+ }
62+
63+ // FastAPI: debug command with uvicorn
64+ func Test_buildDebugPyCommandForModule_FastAPI (t * testing.T ) {
65+ // Arrange
66+ expected := "cd /app && python -m debugpy --listen 0.0.0.0:5678 -m " +
67+ "uvicorn main:app --host $HOST --port $PORT"
68+ gen := PythonStartupScriptGenerator {
69+ DebugPort : "5678" ,
70+ }
71+
72+ // Act
73+ actual := gen .buildDebugPyCommandForModule (
74+ "uvicorn main:app --host $HOST --port $PORT" , "/app" )
75+
76+ // Assert
77+ assert .Equal (t , expected , actual )
78+ }
79+
80+ // FastAPI detection: main.py with FastAPI import, validates detection + all output methods
81+ func Test_fastAPIDetector_detect_mainPy (t * testing.T ) {
82+ // Arrange
83+ dir := t .TempDir ()
84+ os .WriteFile (filepath .Join (dir , "main.py" ),
85+ []byte ("from fastapi import FastAPI\n app = FastAPI()\n " ), 0644 )
86+
87+ detector := & fastAPIDetector {appPath : dir }
88+
89+ // Act & Assert
90+ assert .True (t , detector .detect ())
91+ assert .Equal (t , "main.py" , detector .mainFile )
92+ assert .Equal (t , "-k uvicorn_worker.UvicornWorker main:app" , detector .GetGunicornModuleArg ())
93+ assert .Equal (t , "uvicorn main:app --host $HOST --port $PORT" , detector .GetDebuggableModule ())
94+ }
95+
96+ // FastAPI detection: no FastAPI import should return false
97+ func Test_fastAPIDetector_detect_notFastAPI (t * testing.T ) {
98+ // Arrange
99+ dir := t .TempDir ()
100+ os .WriteFile (filepath .Join (dir , "main.py" ),
101+ []byte ("from flask import Flask\n app = Flask(__name__)\n " ), 0644 )
102+
103+ detector := & fastAPIDetector {appPath : dir }
104+
105+ // Act & Assert
106+ assert .False (t , detector .detect ())
107+ }
108+
109+ // DetectFramework: FastAPI detected before Flask when app.py has FastAPI
110+ func Test_DetectFramework_FastAPI_beforeFlask (t * testing.T ) {
111+ // Arrange
112+ dir := t .TempDir ()
113+ os .WriteFile (filepath .Join (dir , "app.py" ),
114+ []byte ("from fastapi import FastAPI\n app = FastAPI()\n " ), 0644 )
115+
116+ // Act
117+ fw := DetectFramework (dir , "" , "3.14.0" )
118+
119+ // Assert
120+ assert .NotNil (t , fw )
121+ assert .Equal (t , "FastAPI" , fw .Name ())
122+ }
123+
124+ // DetectFramework: Django wins over FastAPI when wsgi.py exists in subdirectory
125+ func Test_DetectFramework_Django_overFastAPI (t * testing.T ) {
126+ // Arrange
127+ dir := t .TempDir ()
128+ subDir := filepath .Join (dir , "myproject" )
129+ os .MkdirAll (subDir , 0755 )
130+ os .WriteFile (filepath .Join (subDir , "wsgi.py" ), []byte ("" ), 0644 )
131+ os .WriteFile (filepath .Join (dir , "main.py" ),
132+ []byte ("from fastapi import FastAPI\n app = FastAPI()\n " ), 0644 )
133+
134+ // Act
135+ fw := DetectFramework (dir , "" , "3.14.0" )
136+
137+ // Assert
138+ assert .NotNil (t , fw )
139+ assert .Equal (t , "Django" , fw .Name ())
140+ }
141+
142+ func Test_buildGunicornCommandForModule_moduleAndPathAndHost (t * testing.T ) {
44143 // Arrange
45144 expected := "GUNICORN_CMD_ARGS=\" --timeout 600 --access-logfile '-' --error-logfile '-'" +
46145 " --bind=0.0.0.0:12345 --chdir=/a/b/c\" gunicorn module.py"
0 commit comments