@@ -86,32 +86,10 @@ func TestReplaceBinary(t *testing.T) {
8686 t .Fatal (err )
8787 }
8888
89- // Point os.Executable to our fake binary by using a symlink
90- // Since we can't override os.Executable, test replaceBinary directly
91- // by calling the internal logic with a known path.
9289 newContent := []byte ("new binary content" )
93-
94- // Write new binary to temp, rename
95- tmp , err := os .CreateTemp (dir , "deepsource.new.*" )
96- if err != nil {
97- t .Fatal (err )
98- }
99- if _ , err := tmp .Write (newContent ); err != nil {
100- t .Fatal (err )
101- }
102- if err := tmp .Chmod (0o755 ); err != nil {
103- t .Fatal (err )
104- }
105- tmp .Close ()
106-
107- bakPath := fakeBin + ".bak"
108- if err := os .Rename (fakeBin , bakPath ); err != nil {
109- t .Fatal (err )
110- }
111- if err := os .Rename (tmp .Name (), fakeBin ); err != nil {
112- t .Fatal (err )
90+ if err := replaceBinaryAt (newContent , fakeBin ); err != nil {
91+ t .Fatalf ("replaceBinaryAt: %v" , err )
11392 }
114- os .Remove (bakPath )
11593
11694 got , err := os .ReadFile (fakeBin )
11795 if err != nil {
@@ -230,40 +208,41 @@ func TestCheckForUpdate_NewerVersion(t *testing.T) {
230208 buildinfo .SetBuildInfo ("2.0.30" , "" , "prod" )
231209
232210 key := runtime .GOOS + "_" + runtime .GOARCH
233- manifest := Manifest {
234- Version : "2.0.40" ,
235- Platforms : map [string ]PlatformInfo {
236- key : {
237- Archive : "deepsource_2.0.40_" + key + ".tar.gz" ,
238- SHA256 : "abc123" ,
239- },
240- },
241- }
242- // Simulate what CheckForUpdate does: fetch manifest, compare, write state
243- newer , _ := IsNewer ("2.0.30" , manifest .Version )
244- if ! newer {
245- t .Fatal ("expected newer=true" )
246- }
247-
248- platform := manifest .Platforms [key ]
249- state := & UpdateState {
250- Version : manifest .Version ,
251- ArchiveURL : buildinfo .BaseURL + "/build/" + platform .Archive ,
252- SHA256 : platform .SHA256 ,
253- CheckedAt : time .Now ().UTC (),
254- }
255- if err := writeUpdateState (state ); err != nil {
256- t .Fatalf ("writeUpdateState: %v" , err )
211+ manifestJSON := fmt .Sprintf (`{
212+ "version": "2.0.40",
213+ "platforms": {
214+ %q: {
215+ "archive": "deepsource_2.0.40_%s.tar.gz",
216+ "sha256": "abc123"
217+ }
218+ }
219+ }` , key , key )
220+
221+ srv := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , _ * http.Request ) {
222+ w .Write ([]byte (manifestJSON ))
223+ }))
224+ defer srv .Close ()
225+
226+ // Point manifest fetch at our test server
227+ origBaseURL := buildinfo .BaseURL
228+ buildinfo .BaseURL = srv .URL
229+ defer func () { buildinfo .BaseURL = origBaseURL }()
230+
231+ if err := CheckForUpdate (srv .Client ()); err != nil {
232+ t .Fatalf ("CheckForUpdate: %v" , err )
257233 }
258234
259235 got , err := ReadUpdateState ()
260236 if err != nil {
261237 t .Fatalf ("ReadUpdateState: %v" , err )
262238 }
239+ if got == nil {
240+ t .Fatal ("expected non-nil state" )
241+ }
263242 if got .Version != "2.0.40" {
264243 t .Errorf ("expected version 2.0.40, got %s" , got .Version )
265244 }
266- expectedURL := fmt .Sprintf ("%s/build/deepsource_2.0.40_%s.tar.gz" , buildinfo . BaseURL , key )
245+ expectedURL := fmt .Sprintf ("%s/build/deepsource_2.0.40_%s.tar.gz" , srv . URL , key )
267246 if got .ArchiveURL != expectedURL {
268247 t .Errorf ("expected archive URL %s, got %s" , expectedURL , got .ArchiveURL )
269248 }
@@ -299,7 +278,7 @@ func TestApplyUpdate_WithStateFile(t *testing.T) {
299278 checksum := sha256 .Sum256 (archive )
300279 checksumHex := hex .EncodeToString (checksum [:])
301280
302- srv := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
281+ srv := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , _ * http.Request ) {
303282 w .Write (archive )
304283 }))
305284 defer srv .Close ()
@@ -314,42 +293,38 @@ func TestApplyUpdate_WithStateFile(t *testing.T) {
314293 t .Fatalf ("writeUpdateState: %v" , err )
315294 }
316295
317- client := srv .Client ()
318-
319- // ApplyUpdate reads the state file internally, so we test it reads correctly.
320- // However, replaceBinary will use os.Executable() which we can't easily mock.
321- // So we test the pieces: state file reading, download, checksum verification.
322-
323- readState , err := ReadUpdateState ()
324- if err != nil {
325- t .Fatalf ("ReadUpdateState: %v" , err )
326- }
327- if readState .Version != "2.0.40" {
328- t .Fatalf ("expected version 2.0.40, got %s" , readState .Version )
296+ // Create a fake binary so replaceBinary can replace it
297+ fakeBin := filepath .Join (t .TempDir (), buildinfo .AppName )
298+ if err := os .WriteFile (fakeBin , []byte ("old binary" ), 0o755 ); err != nil {
299+ t .Fatal (err )
329300 }
330301
331- data , err := downloadFile (client , readState .ArchiveURL )
302+ // Override executablePath to point to our fake binary
303+ origExecPath := executablePath
304+ executablePath = func () (string , error ) { return fakeBin , nil }
305+ defer func () { executablePath = origExecPath }()
306+
307+ ver , err := ApplyUpdate (srv .Client ())
332308 if err != nil {
333- t .Fatalf ("downloadFile : %v" , err )
309+ t .Fatalf ("ApplyUpdate : %v" , err )
334310 }
335-
336- if err := verifyChecksum (data , readState .SHA256 ); err != nil {
337- t .Fatalf ("verifyChecksum: %v" , err )
311+ if ver != "2.0.40" {
312+ t .Errorf ("expected version 2.0.40, got %s" , ver )
338313 }
339314
340- extracted , err := extractFromTarGz (data , buildinfo .AppName )
315+ // Verify the binary was actually replaced
316+ got , err := os .ReadFile (fakeBin )
341317 if err != nil {
342- t .Fatalf ( "extractFromTarGz: %v" , err )
318+ t .Fatal ( err )
343319 }
344- if ! bytes .Equal (extracted , binaryContent ) {
345- t .Errorf ("extracted binary mismatch: got %q, want %q" , extracted , binaryContent )
320+ if ! bytes .Equal (got , binaryContent ) {
321+ t .Errorf ("binary content mismatch: got %q, want %q" , got , binaryContent )
346322 }
347323
348- // Verify clearUpdateState removes the file
349- clearUpdateState ()
350- afterClear , _ := ReadUpdateState ()
351- if afterClear != nil {
352- t .Error ("state file should be removed after clear" )
324+ // Verify state file was cleared
325+ afterApply , _ := ReadUpdateState ()
326+ if afterApply != nil {
327+ t .Error ("state file should be removed after apply" )
353328 }
354329}
355330
0 commit comments