1"""Analysis tests for getting the link name of a versioned library."""
2
3load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
4load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
5load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_import")
6load("//rust:defs.bzl", "rust_shared_library")
7
8LIBNAMES = ["sterling", "cheryl", "lana", "pam", "malory", "cyril"]
9
10def _is_in_argv(argv, version = None):
11    return any(["-ldylib={}{}".format(name, version or "") in argv for name in LIBNAMES])
12
13def _no_version_test_impl(ctx):
14    env = analysistest.begin(ctx)
15    tut = analysistest.target_under_test(env)
16    argv = tut.actions[0].argv
17
18    asserts.true(env, _is_in_argv(argv))
19
20    return analysistest.end(env)
21
22def _prefix_version_test_impl(ctx):
23    env = analysistest.begin(ctx)
24    tut = analysistest.target_under_test(env)
25    argv = tut.actions[0].argv
26
27    asserts.true(env, _is_in_argv(argv, "3.8"))
28
29    return analysistest.end(env)
30
31def _suffix_version_test_impl(ctx):
32    env = analysistest.begin(ctx)
33    tut = analysistest.target_under_test(env)
34    argv = tut.actions[0].argv
35
36    asserts.true(env, _is_in_argv(argv))
37
38    return analysistest.end(env)
39
40no_version_test = analysistest.make(_no_version_test_impl)
41prefix_version_test = analysistest.make(_prefix_version_test_impl)
42suffix_version_test = analysistest.make(_suffix_version_test_impl)
43
44def _test_linux():
45    rust_shared_library(
46        name = "linux_no_version",
47        srcs = ["a.rs"],
48        edition = "2018",
49        deps = [":import_libsterling.so"],
50        target_compatible_with = ["@platforms//os:linux"],
51    )
52    cc_import(
53        name = "import_libsterling.so",
54        shared_library = "libsterling.so",
55    )
56    cc_binary(
57        name = "libsterling.so",
58        srcs = ["b.c"],
59        linkshared = True,
60    )
61    no_version_test(
62        name = "linux_no_version_test",
63        target_under_test = ":linux_no_version",
64        target_compatible_with = ["@platforms//os:linux"],
65    )
66
67    rust_shared_library(
68        name = "linux_suffix_version",
69        srcs = ["a.rs"],
70        edition = "2018",
71        deps = [":import_libcheryl.so.3.8", ":import_libcheryl.so"],
72        target_compatible_with = ["@platforms//os:linux"],
73    )
74    cc_import(
75        name = "import_libcheryl.so.3.8",
76        shared_library = "libcheryl.so.3.8",
77    )
78    cc_binary(
79        name = "libcheryl.so.3.8",
80        srcs = ["b.c"],
81        linkshared = True,
82    )
83    cc_import(
84        name = "import_libcheryl.so",
85        shared_library = "libcheryl.so",
86    )
87    copy_file(
88        name = "copy_unversioned",
89        src = ":libcheryl.so.3.8",
90        out = "libcheryl.so",
91    )
92    suffix_version_test(
93        name = "linux_suffix_version_test",
94        target_under_test = ":linux_suffix_version",
95        target_compatible_with = ["@platforms//os:linux"],
96    )
97
98    return [
99        ":linux_no_version_test",
100        ":linux_suffix_version_test",
101    ]
102
103def _test_macos():
104    rust_shared_library(
105        name = "no_version",
106        srcs = ["a.rs"],
107        edition = "2018",
108        deps = [":import_liblana.dylib"],
109        target_compatible_with = ["@platforms//os:macos"],
110    )
111    cc_import(
112        name = "import_liblana.dylib",
113        shared_library = "liblana.dylib",
114    )
115    cc_binary(
116        name = "liblana.dylib",
117        srcs = ["b.c"],
118        linkshared = True,
119    )
120    no_version_test(
121        name = "macos_no_version_test",
122        target_under_test = ":no_version",
123        target_compatible_with = ["@platforms//os:macos"],
124    )
125
126    rust_shared_library(
127        name = "prefix_version",
128        srcs = ["a.rs"],
129        edition = "2018",
130        deps = [":import_libpam3.8.dylib"],
131        target_compatible_with = ["@platforms//os:macos"],
132    )
133    cc_import(
134        name = "import_libpam3.8.dylib",
135        shared_library = "libpam3.8.dylib",
136    )
137    cc_binary(
138        name = "libpam3.8.dylib",
139        srcs = ["b.c"],
140        linkshared = True,
141    )
142    prefix_version_test(
143        name = "macos_prefix_version_test",
144        target_under_test = ":prefix_version",
145        target_compatible_with = ["@platforms//os:macos"],
146    )
147
148    return [
149        ":macos_no_version_test",
150        ":macos_prefix_version_test",
151    ]
152
153def _test_windows():
154    rust_shared_library(
155        name = "windows_no_version",
156        srcs = ["a.rs"],
157        edition = "2018",
158        deps = [":import_malory.dll"],
159        target_compatible_with = ["@platforms//os:windows"],
160    )
161    cc_import(
162        name = "import_malory.dll",
163        interface_library = ":malory.lib",
164        shared_library = "malory.dll",
165    )
166    cc_binary(
167        name = "malory.dll",
168        srcs = ["b.c"],
169        linkshared = True,
170    )
171    native.filegroup(
172        name = "malory_interface_lib",
173        srcs = [":malory.dll"],
174        output_group = "interface_library",
175    )
176    copy_file(
177        name = "copy_malory_interface_lib",
178        src = ":malory_interface_lib",
179        out = "malory.lib",
180    )
181    no_version_test(
182        name = "windows_no_version_test",
183        target_under_test = ":windows_no_version",
184        target_compatible_with = ["@platforms//os:windows"],
185    )
186
187    rust_shared_library(
188        name = "windows_prefix_version",
189        srcs = ["a.rs"],
190        edition = "2018",
191        deps = [":import_cyril3.8.dll"],
192        target_compatible_with = ["@platforms//os:windows"],
193    )
194    cc_import(
195        name = "import_cyril3.8.dll",
196        interface_library = ":cyril3.8.lib",
197        shared_library = "cyril3.8.dll",
198    )
199    cc_binary(
200        name = "cyril3.8.dll",
201        srcs = ["b.c"],
202        linkshared = True,
203    )
204    native.filegroup(
205        name = "cyril_interface_lib",
206        srcs = [":cyril3.8.dll"],
207        output_group = "interface_library",
208    )
209    copy_file(
210        name = "copy_cyril_interface_lib",
211        src = ":cyril_interface_lib",
212        out = "cyril3.8.lib",
213    )
214    prefix_version_test(
215        name = "windows_prefix_version_test",
216        target_under_test = ":windows_prefix_version",
217        target_compatible_with = ["@platforms//os:windows"],
218    )
219
220    return [
221        ":windows_no_version_test",
222        ":windows_prefix_version_test",
223    ]
224
225def versioned_libs_analysis_test_suite(name):
226    """Analysis tests for getting the link name of a versioned library.
227
228    Args:
229        name: the test suite name
230    """
231    tests = []
232    tests += _test_linux()
233    tests += _test_macos()
234    tests += _test_windows()
235
236    native.test_suite(
237        name = name,
238        tests = tests,
239    )
240