1+ package compose
2+
3+ import (
4+ "fmt"
5+ "os"
6+ "path/filepath"
7+ "strings"
8+ "testing"
9+
10+ "github.com/ASSERT-KTH/go-cryptoapi/internal/dataset"
11+ )
12+
13+ func TestGenerateComposeHeader (t * testing.T ) {
14+ want := "version: '3.8'\n \n services:\n "
15+ if got := generateComposeHeader (); got != want {
16+ t .Errorf ("generateComposeHeader() = %q; want %q" , got , want )
17+ }
18+ }
19+
20+ func TestGenerateVolumeConfig (t * testing.T ) {
21+ got := generateVolumeConfig ()
22+ if ! strings .Contains (got , "volumes:" ) {
23+ t .Error ("generateVolumeConfig missing 'volumes:'" )
24+ }
25+ if ! strings .Contains (got , "driver: local" ) {
26+ t .Error ("generateVolumeConfig missing 'driver: local'" )
27+ }
28+ if ! strings .Contains (got , "device: ${BASE_DIR}/gopher" ) {
29+ t .Error ("generateVolumeConfig missing expected device path" )
30+ }
31+ }
32+
33+ func TestGenerateServiceName (t * testing.T ) {
34+ cases := []struct { repo , id , want string }{
35+ {"github.com/user/repo" , "123" , "user-repo-123" },
36+ {"user/repo" , "id" , "user-repo-id" },
37+ {"example" , "ID" , "example-id" },
38+ }
39+ for _ , c := range cases {
40+ if got := generateServiceName (c .repo , c .id ); got != c .want {
41+ t .Errorf ("generateServiceName(%q, %q) = %q; want %q" , c .repo , c .id , got , c .want )
42+ }
43+ }
44+ }
45+
46+ func TestGenerateServiceStr (t * testing.T ) {
47+ repo := "https://example.com/foo"
48+ gitTag := "v1.0.0"
49+ goVer := "1.15"
50+ svcName := "service-name"
51+ analysisDir := "analysis/dir"
52+ out := generateServiceStr (repo , gitTag , goVer , svcName , analysisDir )
53+ tests := []string {
54+ fmt .Sprintf (" %s:\n " , svcName ),
55+ "build:" ,
56+ "context: ." ,
57+ fmt .Sprintf ("REPO_URL: \" %s\" " , repo ),
58+ fmt .Sprintf ("GIT_TAG: \" %s\" " , gitTag ),
59+ fmt .Sprintf ("GO_VERSION: \" %s\" " , goVer ),
60+ fmt .Sprintf ("container_name: %s" , svcName ),
61+ "gopher-shared:/analysis/gopher" ,
62+ fmt .Sprintf ("${BASE_DIR}/%s:/analysis/repo/scan_results" , analysisDir ),
63+ }
64+ for _ , sub := range tests {
65+ if ! strings .Contains (out , sub ) {
66+ t .Errorf ("generateServiceStr missing %q" , sub )
67+ }
68+ }
69+ }
70+
71+ func TestWriteComposeFile (t * testing.T ) {
72+ dir := t .TempDir ()
73+ content := "hello compose"
74+ path , err := WriteComposeFile (dir , content )
75+ if err != nil {
76+ t .Fatalf ("WriteComposeFile error: %v" , err )
77+ }
78+ data , err := os .ReadFile (path )
79+ if err != nil {
80+ t .Fatalf ("failed to read file: %v" , err )
81+ }
82+ if string (data ) != content {
83+ t .Errorf ("file content = %q; want %q" , string (data ), content )
84+ }
85+ if filepath .Base (path ) != "compose.yaml" {
86+ t .Errorf ("file name = %q; want %q" , filepath .Base (path ), "compose.yaml" )
87+ }
88+ }
89+
90+ func TestNewComposer (t * testing.T ) {
91+ // ModuleDataset
92+ modDS := & dataset.ModuleDataset {Modules : []dataset.Module {}}
93+ cMod := NewComposer (modDS , "outdir" , 2 )
94+ mc , ok := cMod .(* ModComposer )
95+ if ! ok {
96+ t .Fatalf ("NewComposer(ModuleDataset) returned %T; want *ModComposer" , cMod )
97+ }
98+ if mc .OutDir != "outdir" {
99+ t .Errorf ("ModComposer.Config.OutDir = %q; want %q" , mc .OutDir , "outdir" )
100+ }
101+ if mc .Parallelism != 2 {
102+ t .Errorf ("ModComposer.Config.Parallelism = %d; want %d" , mc .Parallelism , 2 )
103+ }
104+ // VulnerabilityDataset
105+ vulDS := & dataset.VulnerabilityDataset {Vulnerabilities : []dataset.Vulnerability {}}
106+ cVul := NewComposer (vulDS , "dir2" , 3 )
107+ vc , ok := cVul .(* VulComposer )
108+ if ! ok {
109+ t .Fatalf ("NewComposer(VulnerabilityDataset) returned %T; want *VulComposer" , cVul )
110+ }
111+ if vc .OutDir != "dir2" {
112+ t .Errorf ("VulComposer.Config.OutDir = %q; want %q" , vc .OutDir , "dir2" )
113+ }
114+ if vc .Parallelism != 3 {
115+ t .Errorf ("VulComposer.Config.Parallelism = %d; want %d" , vc .Parallelism , 3 )
116+ }
117+ // Default parallelism when <= 0
118+ cDef := NewComposer (modDS , "" , 0 )
119+ mc2 := cDef .(* ModComposer )
120+ if mc2 .Parallelism != 4 {
121+ t .Errorf ("Default Parallelism = %d; want %d" , mc2 .Parallelism , 4 )
122+ }
123+ }
124+
125+ // fakeDS implements dataset.Dataset but is not a ModuleDataset or VulnerabilityDataset
126+ type fakeDS struct {}
127+ func (f * fakeDS ) Count () int { return 0 }
128+ func (f * fakeDS ) Type () dataset.DatasetType { return "" }
129+ func (f * fakeDS ) String () string { return "" }
130+ func (f * fakeDS ) ID () string { return "" }
131+
132+ func TestNewComposerUnsupported (t * testing.T ) {
133+ defer func () {
134+ if r := recover (); r == nil {
135+ t .Errorf ("NewComposer did not panic for unsupported dataset" )
136+ }
137+ }()
138+ _ = NewComposer (& fakeDS {}, "x" , 1 )
139+ }
0 commit comments